package com.ecep.contract.serializer;

import com.ecep.contract.model.IdentityEntity;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * 自定义的反序列化器修改器，用于实现类似Hibernate的代理对象功能
 */
public class ProxyObjectDeserializerModifier extends BeanDeserializerModifier {

    private final ObjectMapper objectMapper;

    public ProxyObjectDeserializerModifier(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    @SuppressWarnings("unchecked")
    public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
            BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
        // 检查是否是IdentityEntity的实现类
        if (IdentityEntity.class.isAssignableFrom(beanDesc.getBeanClass())) {
            // 返回包装后的反序列化器，处理代理对象的创建
            return new ProxyObjectDeserializer((JsonDeserializer<Object>) deserializer,
                    beanDesc.getBeanClass(), objectMapper);
        }
        return deserializer;
    }

    /**
     * 代理对象反序列化器，用于处理对象字段的懒加载
     */
    private static class ProxyObjectDeserializer extends StdDeserializer<Object> implements ResolvableDeserializer {

        private final JsonDeserializer<Object> delegate;
        private final Class<?> targetClass;
        private final ObjectMapper objectMapper;

        @SuppressWarnings("unchecked")
        public ProxyObjectDeserializer(JsonDeserializer<Object> delegate,
                Class<?> targetClass, ObjectMapper objectMapper) {
            super((Class<Object>) targetClass);
            this.delegate = delegate;
            this.targetClass = targetClass;
            this.objectMapper = objectMapper;
        }

        @Override
        public Object deserialize(com.fasterxml.jackson.core.JsonParser p,
                com.fasterxml.jackson.databind.DeserializationContext ctxt) throws java.io.IOException {
            // 首先检查是否是一个只有id的对象节点
            if (p.isExpectedStartObjectToken()) {
                ObjectNode node = p.readValueAsTree();

                // 检查是否只包含id和_proxy_字段
                if (node.has("id") && node.has("_proxy_")) {
                    try {
                        // 创建目标类的实例
                        Object instance = targetClass.getDeclaredConstructor().newInstance();

                        // 设置id字段
                        if (instance instanceof IdentityEntity) {
                            ((IdentityEntity) instance).setId(node.get("id").asInt());
                        }
                        return instance;
                    } catch (Exception e) {
                        // 如果创建实例失败，回退到原始反序列化器
                        return delegate.deserialize(p, ctxt);
                    }
                }
                // 对于普通对象，使用原始反序列化器
                return delegate.deserialize(p, ctxt);
            }
            // 对于非对象类型，使用原始反序列化器
            return delegate.deserialize(p, ctxt);
        }

        @Override
        public void resolve(DeserializationContext ctxt) throws JsonMappingException {
            // 如果委托的反序列化器也是ResolvableDeserializer，则调用其resolve方法
            if (delegate instanceof ResolvableDeserializer) {
                ((ResolvableDeserializer) delegate).resolve(ctxt);
            }
        }

    }
}