package com.ecep.contract.config;

import java.io.IOException;

import org.hibernate.proxy.HibernateProxy;

import com.ecep.contract.model.IdentityEntity;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

/**
 * 用于处理Hibernate代理对象的反序列化器
 * 专门处理序列化时写入的id和_proxy_字段
 */
class HibernateProxyDeserializer extends StdDeserializer<HibernateProxy> {

    protected HibernateProxyDeserializer() {
        super(HibernateProxy.class);
    }

    @Override
    public HibernateProxy deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // 检查是否是对象类型
        if (p.currentToken() != JsonToken.START_OBJECT) {
            return (HibernateProxy) ctxt.handleUnexpectedToken(HibernateProxy.class, p);
        }

        // 读取对象字段
        JsonToken token;
        Object id = null;
        String proxyClassName = null;
        
        // 解析JSON对象的所有字段
        while ((token = p.nextToken()) != JsonToken.END_OBJECT) {
            if (token == JsonToken.FIELD_NAME) {
                String fieldName = p.getCurrentName();
                p.nextToken(); // 移动到字段值
                
                if ("id".equals(fieldName)) {
                    id = p.readValueAs(Object.class);
                } else if ("_proxy_".equals(fieldName)) {
                    proxyClassName = p.getText();
                }
            }
        }

        // 如果同时存在id和_proxy_字段，说明这是一个Hibernate代理对象
        if (id != null && proxyClassName != null) {

            HibernateProxy proxy = null;

            try {
                // 尝试获取实体类类型（去掉代理类名中的字节码增强部分）
                // 代理类名通常格式为：com.ecep.contract.model.Entity$HibernateProxy$XXXX
                int proxyIndex = proxyClassName.indexOf("$HibernateProxy$");
                String entityClassName = proxyIndex > 0 ? proxyClassName.substring(0, proxyIndex) : proxyClassName;
                
                // 加载实体类
                Class<?> entityClass = Class.forName(entityClassName);
                
                // 检查是否是IdentityEntity类型
                if (IdentityEntity.class.isAssignableFrom(entityClass)) {
                    // 创建实体对象并设置ID
                    IdentityEntity entity = (IdentityEntity) entityClass.getDeclaredConstructor().newInstance();
                    if (id instanceof Number) {
                        entity.setId(((Number) id).intValue());
                    } else {
                        // 处理非数值类型的ID
                        try {
                            entity.setId(Integer.parseInt(id.toString()));
                        } catch (NumberFormatException e) {
                            // 如果无法转换为Integer，记录警告但继续处理
                        }
                    }
                    return (HibernateProxy) entity;
                }
            } catch (Exception e) {
                // 发生异常时，返回一个只包含ID的简单对象
                // 这可以避免反序列化失败
                return (HibernateProxy) createSimpleIdObject(id);
            }
        }

        // 如果不是代理对象或处理失败，回退到默认的反序列化逻辑
        // 使用 skipChildren() 确保解析器在正确的位置开始默认反序列化
        if (p.currentToken() != JsonToken.START_OBJECT) {
            // 尝试查找对象开始位置
            while (p.currentToken() != null && p.currentToken() != JsonToken.START_OBJECT) {
                p.nextToken();
            }
        }
        if (p.currentToken() == JsonToken.START_OBJECT) {
            return (HibernateProxy) ctxt.readValue(p, Object.class);
        }
        return null;
    }
    
    /**
     * 创建一个只包含ID字段的简单对象
     */
    private Object createSimpleIdObject(final Object id) {
        return new Object() {
            @Override
            public String toString() {
                return "ProxyObject[id=" + id + "]";
            }
        };
    }
}