package xtools.boot.mask.serializer;

import lombok.extern.slf4j.Slf4j;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.TokenStreamContext;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueSerializer;
import xtools.boot.mask.MaskCustom;
import xtools.boot.mask.anntation.Mask;
import xtools.boot.mask.utils.MaskIgnoreUtils;
import xtools.core.StringUtils;
import xtools.core.extend.MaskUtils;

import java.lang.reflect.Field;
import java.util.Objects;

/**
 * <p>Title : MaskSerializer</p>
 * <p>Description : MaskSerializer</p>
 * <p>DevelopTools : Idea_x64_v2026.1</p>
 * <p>DevelopSystem : macOS Sequoia 15.7.5</p>
 * <p>Company : org.xujun</p>
 *
 * @author : XuJun
 * @version : 5.0.0
 * @date : 2026/1/9 10:08
 */
@Slf4j
public class MaskSerializer extends ValueSerializer<String> {

    /**
     * 序列化字符串
     *
     * @param value   待处理的字符串
     * @param gen     JsonGenerator
     * @param context SerializationContext
     * @throws JacksonException JacksonException
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializationContext context) throws JacksonException {
        if (StringUtils.isBlank(value)) {
            gen.writeString(value);
            return;
        }
        value = value.trim();
        TokenStreamContext streamContext = gen.streamWriteContext();
        if (Objects.isNull(streamContext)) {
            gen.writeString(value);
            return;
        }
        try {
            Field field = streamContext.currentValue().getClass().getDeclaredField(streamContext.currentName());
            // 获取注解
            Mask mask = field.getAnnotation(Mask.class);
            if (mask == null) {
                gen.writeString(value);
                return;
            }
            // 判断是否总是脱敏
            if (!mask.always()) {
                // 判断是否忽略脱敏
                if (MaskIgnoreUtils.isIgnore()) {
                    gen.writeString(value);
                    return;
                }
            }
            gen.writeString(mask(value, mask));
        } catch (Exception e) {
            log.error("脱敏处理异常", e);
            gen.writeString(value);
        }
    }

    /**
     * 脱敏处理
     *
     * @param value 待处理的字符串
     * @param mask  脱敏注解
     * @return 脱敏后的字符串
     * @throws Exception 异常
     */
    private String mask(String value, Mask mask) throws Exception {
        String maskString = mask.maskChar();
        return switch (mask.value()) {
            case PASSWORD -> MaskUtils.password(value, maskString);
            case MOBILE_PHONE -> MaskUtils.mobilePhone(value, maskString);
            case EMAIL -> MaskUtils.email(value, maskString);
            case CHINESE_NAME -> MaskUtils.chineseName(value, maskString);
            case ADDRESS -> MaskUtils.address(value, maskString);
            case ID_CARD -> MaskUtils.idCard(value, maskString);
            case BANK_CARD -> MaskUtils.bankCard(value, maskString);
            case CUSTOM -> customMask(value, mask);
        };
    }

    /**
     * 自定义脱敏处理
     *
     * @param value 待处理的字符串
     * @param mask  脱敏注解
     * @return 脱敏后的字符串
     * @throws Exception 异常
     */
    private String customMask(String value, Mask mask) throws Exception {
        Class<? extends MaskCustom> custom = mask.custom();
        return custom.getDeclaredConstructor().newInstance().mask(value, mask);
    }

}
