package com.lingniu.ingest.protocol.gb32960.codec.profile;

import com.lingniu.ingest.protocol.gb32960.codec.InfoBlockParser;
import com.lingniu.ingest.protocol.gb32960.codec.InfoBlockParserRegistry;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 命名 profile → {@link InfoBlockParserRegistry} 映射。
 *
 * <p>构造时接收：
 * <ul>
 *   <li>{@code defaultParsers} —— 标准 GB/T 32960 parser 集合（v2016 + v2025）
 *   <li>{@code catalog} —— vendor 扩展套件目录
 *   <li>{@code enabledExtensionNames} —— 在配置文件里被引用过的 vendor 套件名集合
 * </ul>
 *
 * 构造内部为 default profile 和每个 enabled 扩展套件分别构建一个 registry：
 * 套件 registry = default parsers + catalog 里该套件的 parsers。运行期通过
 * {@link #forProfile(String)} 按名字查找；查不到或传 null 时返回 default。
 */
public class Gb32960ProfileRegistry {

    /** 约定的默认 profile 名（不会出现在配置里，仅作为 forProfile(null) 的 fallback 标识）。 */
    public static final String DEFAULT_PROFILE = "__default__";

    private final InfoBlockParserRegistry defaultRegistry;
    private final Map<String, InfoBlockParserRegistry> registriesByProfile;

    public Gb32960ProfileRegistry(List<InfoBlockParser> defaultParsers,
                                  VendorExtensionCatalog catalog,
                                  Set<String> enabledExtensionNames) {
        this.defaultRegistry = new InfoBlockParserRegistry(defaultParsers);
        Map<String, InfoBlockParserRegistry> map = new HashMap<>();
        for (String name : enabledExtensionNames) {
            List<InfoBlockParser> vendorParsers = catalog.parsersFor(name);
            if (vendorParsers.isEmpty()) {
                throw new IllegalStateException(
                        "vendor extension '" + name + "' referenced in config but not present in catalog. "
                                + "Available: " + catalog.names());
            }
            List<InfoBlockParser> combined = new ArrayList<>(defaultParsers.size() + vendorParsers.size());
            combined.addAll(defaultParsers);
            // vendor parser 只新增扩展 typeCode，不应覆盖标准 parser；若未来需覆盖，必须显式设计优先级。
            combined.addAll(vendorParsers);
            map.put(name, new InfoBlockParserRegistry(combined));
        }
        this.registriesByProfile = Map.copyOf(map);
    }

    /** 按 profile 名取 registry；null 或未注册的名字返回默认 registry。 */
    public InfoBlockParserRegistry forProfile(String profileName) {
        if (profileName == null) return defaultRegistry;
        InfoBlockParserRegistry r = registriesByProfile.get(profileName);
        return r != null ? r : defaultRegistry;
    }

    public InfoBlockParserRegistry defaultRegistry() {
        return defaultRegistry;
    }
}
