package com.njcn.gather.icd.mapping.component;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.njcn.gather.icd.mapping.config.MappingModuleConfig;
import com.njcn.gather.icd.mapping.pojo.bo.template.DefaultTemplate;
import com.njcn.gather.icd.mapping.utils.JsonUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 默认配置加载器。
 *
 * 说明：
 * 1. 直接读取 DefaultCfg.txt。
 * 2. 读取后按 DefaultTemplate 原始模型反序列化。
 */
@Service
public class DefaultTemplateLoader {

    /** 模块配置，提供默认模板路径等运行参数。 */
    private final MappingModuleConfig moduleConfig;

    /** 模板反序列化使用的 Jackson 实例。 */
    private final ObjectMapper objectMapper;

    public DefaultTemplateLoader(MappingModuleConfig moduleConfig) {
        this.moduleConfig = moduleConfig;
        this.objectMapper = new ObjectMapper();
        this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 加载并校验默认映射模板。
     *
     * 返回值会直接参与索引候选分析和最终 MappingDocument 生成。
     */
    public DefaultTemplate load() {
        try {
            ClassPathResource resource = new ClassPathResource(moduleConfig.getDefaultTemplatePath());
            if (!resource.exists()) {
                throw new IllegalArgumentException("默认模板文件不存在：" + moduleConfig.getDefaultTemplatePath());
            }
            byte[] bytes = readAllBytes(resource);
            if (bytes.length == 0) {
                throw new IllegalArgumentException("默认模板文件为空");
            }
            String json = new String(bytes, StandardCharsets.UTF_8);
            json = JsonUtils.sanitizeJson(json);
            DefaultTemplate template = objectMapper.readValue(json, DefaultTemplate.class);
            List<String> problems = template.verify();
            if (!problems.isEmpty()) {
                throw new IllegalArgumentException("DefaultCfg.txt 校验失败：" + String.join("；", problems));
            }
            return template;
        } catch (Exception ex) {
            throw new IllegalArgumentException("加载 DefaultCfg.txt 失败：" + ex.getMessage(), ex);
        }
    }

    /**
     * 读取 classpath 资源的完整字节内容。
     */
    private byte[] readAllBytes(ClassPathResource resource) throws Exception {
        try (InputStream inputStream = resource.getInputStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[4096];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            return outputStream.toByteArray();
        }
    }
}
