package com.njzscloud.common.core.fastjson.serializer;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.util.TypeUtils;
import com.alibaba.fastjson2.writer.ObjectWriter;
import com.njzscloud.common.core.ienum.Dict;
import com.njzscloud.common.core.ienum.DictInt;
import com.njzscloud.common.core.ienum.DictStr;
import com.njzscloud.common.core.ienum.IEnum;

import java.lang.reflect.Type;

/**
 * Dict 枚举的 Fastjson 序列化器<br/>
 * 使用方式（二选一即可）: <br/>
 * 1、在字段上使用 JSONField 进行指定<br/>
 * 如，@JSONField(serializeUsing = DictObjectSerializer.class)<br/>
 * 2、在枚举类上使用 JSONType 进行指定（在接口上指定无效）<br/>
 * 如，@JSONType(writeEnumAsJavaBean = true, serializer = DictObjectSerializer.class)<br/><br/>
 * JSON 格式<br/>
 * 1、枚举不是其他对象的属性<br/>
 * <pre>
 * {
 *   "type": "", // 枚举全限定类名, 反序列化时会用到
 *   "name": "", // name 属性
 *   "ordinal": 0, // ordinal 属性
 *   "val": 1,  // val 属性(字符串/数字), 反序列化时会用到
 *   "txt": "1" // txt 属性
 * }</pre>
 * 2、枚举是其他对象的属性<br/>
 * <pre>
 * {
 *   // ... 其他属性
 *   "原字段名称": 1, // val 属性(字符串/数字), 反序列化时会用到
 *   "原字段名称Txt": "1" //  txt 属性
 * }</pre>
 *
 * @see Dict
 * @see DictInt
 * @see DictStr
 */
public class DictObjectSerializer implements ObjectWriter<Dict> {

    @Override
    public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        if (object == null) {
            jsonWriter.writeNull();
            return;
        }

        if (fieldType == null) {
            Dict<?> dict = (Dict<?>) object;
            jsonWriter.startObject();

            jsonWriter.writeName(IEnum.ENUM_TYPE);
            jsonWriter.writeColon();
            jsonWriter.writeString(dict.getClass().getName());

            jsonWriter.writeName(IEnum.ENUM_NAME);
            jsonWriter.writeColon();
            jsonWriter.writeString(((Enum<?>) dict).name());

            jsonWriter.writeName(IEnum.ENUM_ORDINAL);
            jsonWriter.writeColon();
            jsonWriter.writeInt32(((Enum<?>) dict).ordinal());

            jsonWriter.writeName(Dict.ENUM_VAL);
            jsonWriter.writeColon();
            jsonWriter.writeAny(dict.getVal());

            jsonWriter.writeName(Dict.ENUM_TXT);
            jsonWriter.writeColon();
            jsonWriter.writeString(dict.getTxt());

            jsonWriter.endObject();
        } else {
            Class<?> clazz = TypeUtils.getClass(fieldType);

            if (DictInt.class.isAssignableFrom(clazz)) {
                DictInt dictInt = (DictInt) object;
                jsonWriter.writeInt32(dictInt.getVal());

                jsonWriter.writeName(fieldName + "Txt");
                jsonWriter.writeColon();
                jsonWriter.writeString(dictInt.getTxt());
            } else if (DictStr.class.isAssignableFrom(clazz)) {
                DictStr dictStr = (DictStr) object;
                jsonWriter.writeString(dictStr.getVal());
                jsonWriter.writeName(fieldName + "Txt");
                jsonWriter.writeColon();
                jsonWriter.writeString(dictStr.getTxt());
            } else {
                jsonWriter.writeNull();
            }
        }
    }
}
