package tech.easyflow.ai.easyagents.tool;

import org.springframework.util.StringUtils;

import java.math.BigInteger;
import java.util.regex.Pattern;

/**
 * 聊天工具名称辅助类。
 *
 * <p>聊天工具名称最终会作为 OpenAI-compatible 协议里的 function.name 发给上游模型，
 * 因此在启用英文名称时需要确保名称稳定且满足 ASCII 约束。</p>
 *
 * @author Codex
 * @since 2026-05-11
 */
public final class ChatToolNameHelper {

    private static final Pattern SAFE_TOOL_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+$");

    private ChatToolNameHelper() {
    }

    /**
     * 解析聊天工具名称。
     *
     * @param needEnglishName 是否优先使用英文名称
     * @param englishName 英文名称
     * @param displayName 展示名称
     * @param fallbackPrefix 安全兜底名前缀
     * @param resourceId 资源 ID
     * @return 最终工具名称
     */
    public static String resolveToolName(boolean needEnglishName,
                                         String englishName,
                                         String displayName,
                                         String fallbackPrefix,
                                         BigInteger resourceId) {
        if (!needEnglishName) {
            return StringUtils.hasText(displayName) ? displayName : buildFallbackName(fallbackPrefix, resourceId);
        }
        if (StringUtils.hasText(englishName) && SAFE_TOOL_NAME_PATTERN.matcher(englishName).matches()) {
            return englishName;
        }
        return buildFallbackName(fallbackPrefix, resourceId);
    }

    /**
     * 判断工具名称是否满足 OpenAI-compatible function.name 约束。
     *
     * @param name 待检查名称
     * @return 名称合法返回 true，否则返回 false
     */
    public static boolean isSafeToolName(String name) {
        return StringUtils.hasText(name) && SAFE_TOOL_NAME_PATTERN.matcher(name).matches();
    }

    /**
     * 构建稳定的安全兜底工具名称。
     *
     * @param fallbackPrefix 安全兜底名前缀
     * @param resourceId 资源 ID
     * @return 安全兜底工具名称
     */
    public static String buildFallbackName(String fallbackPrefix, BigInteger resourceId) {
        String prefix = StringUtils.hasText(fallbackPrefix) ? fallbackPrefix : "tool";
        String suffix = resourceId == null ? "unknown" : resourceId.toString();
        return prefix + "_" + suffix;
    }
}
