package com.easyagents.agent.runtime.knowledge;

import com.easyagents.agent.runtime.AgentRuntimeException;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
import java.util.regex.Pattern;

/**
 * Agent 知识库工具名称规范。
 */
public final class AgentKnowledgeToolNames {

    /**
     * 知识库工具名称前缀。
     */
    public static final String PREFIX = "retrieve_knowledge_";

    /**
     * OpenAI-compatible Function Call 的通用名称长度上限。
     */
    public static final int MAX_TOOL_NAME_LENGTH = 64;

    private static final int HASH_LENGTH = 8;
    private static final Pattern SAFE_RUNTIME_NAME = Pattern.compile("^[A-Za-z0-9_-]+$");

    /**
     * 禁止实例化工具类。
     */
    private AgentKnowledgeToolNames() {
    }

    /**
     * 根据调用方运行名生成稳定的知识库工具名。
     *
     * <p>超长名称保留可读前缀并追加稳定短哈希，避免不同模型服务对 Function Call
     * 名称长度限制不一致。</p>
     *
     * @param runtimeName 调用方提供的英文运行名
     * @return 合法且稳定的工具名
     * @throws AgentRuntimeException 运行名为空或包含非法字符时抛出
     */
    public static String build(String runtimeName) {
        String normalized = runtimeName == null ? "" : runtimeName.trim();
        if (normalized.isEmpty()) {
            throw new AgentRuntimeException("Knowledge runtime name is required.");
        }
        if (!SAFE_RUNTIME_NAME.matcher(normalized).matches()) {
            throw new AgentRuntimeException(
                    "Knowledge runtime name must contain only letters, numbers, underscores, or hyphens: "
                            + normalized);
        }
        String toolName = PREFIX + normalized;
        if (toolName.length() <= MAX_TOOL_NAME_LENGTH) {
            return toolName;
        }
        String hash = shortHash(normalized);
        int readableLength = MAX_TOOL_NAME_LENGTH - PREFIX.length() - HASH_LENGTH - 1;
        return PREFIX + normalized.substring(0, readableLength) + "_" + hash;
    }

    /**
     * 计算用于超长工具名消歧的稳定短哈希。
     *
     * @param value 原始运行名
     * @return 八位十六进制哈希
     */
    private static String shortHash(String value) {
        try {
            byte[] digest = MessageDigest.getInstance("SHA-256")
                    .digest(value.getBytes(StandardCharsets.UTF_8));
            return HexFormat.of().formatHex(digest).substring(0, HASH_LENGTH);
        } catch (NoSuchAlgorithmException exception) {
            throw new IllegalStateException("SHA-256 is unavailable.", exception);
        }
    }
}
