import { BUILTIN_FUNCTION_TYPES } from "../typeChecker/builtins.js";
import { JS_GLOBALS, lookupJsMember } from "../typeChecker/resolveCall.js";
import { formatTypeHint } from "../utils/formatType.js";
/**
 * Format a BuiltinSignature as a callable type string. Shape:
 *   (T1, T2, ...) => R
 * Variadic params (`restParam`) render as `...T[]`.
 */
function formatSig(sig) {
    const parts = sig.params.map((p) => p === "any" ? "any" : formatTypeHint(p));
    if (sig.restParam !== undefined) {
        const rest = sig.restParam === "any" ? "any" : formatTypeHint(sig.restParam);
        parts.push(`...${rest}[]`);
    }
    const ret = sig.returnType === "any" ? "any" : formatTypeHint(sig.returnType);
    return `(${parts.join(", ")}) => ${ret}`;
}
/**
 * Hover info for keyword-like language constructs that don't parse as a
 * regular function call (and so aren't in BUILTIN_FUNCTION_TYPES) but still
 * deserve a hover doc.
 */
const KEYWORD_BUILTIN_HOVERS = {
    interrupt: {
        sig: "interrupt <kind>(message: string, payload?: Record<string, any>)",
        description: "Throw an interrupt of the given kind. The current execution state is captured so that, once responded to, execution resumes from exactly this point.",
    },
    schema: {
        sig: "schema(T)",
        description: "Expression that returns the Zod schema for a type `T`. Useful when passing a schema to a TypeScript function or validator.",
    },
    debugger: {
        sig: 'debugger(label?: string)',
        description: "No-op when running the agent normally, but pauses execution when running under the Agency debugger. Accepts an optional label string.",
    },
};
/**
 * Hover info for a name that may be a language primitive or JS global.
 * Returns a markdown-formatted string ready for `Hover.contents.value`,
 * or `null` if the name isn't recognized.
 *
 * Currently covers:
 *   - True language primitives in BUILTIN_FUNCTION_TYPES (success,
 *     failure, llm, fork, race, …).
 *   - Keyword-like constructs (interrupt, schema, debugger) via
 *     KEYWORD_BUILTIN_HOVERS — these don't go through BUILTIN_FUNCTION_TYPES
 *     because they parse as their own AST node, but we still want hover
 *     docs for them.
 *   - Flat callable JS globals with a populated `sig` (parseInt, …).
 *   - JS namespace bases (JSON, Math, …) — describes the namespace.
 *
 * Stdlib functions (print, fetch, …) come through importedFunctions,
 * which the existing semantic-symbol path already handles.
 */
export function lookupBuiltinHover(name) {
    if (Object.prototype.hasOwnProperty.call(BUILTIN_FUNCTION_TYPES, name)) {
        const sig = BUILTIN_FUNCTION_TYPES[name];
        const lines = [
            "```agency",
            `${name}: ${formatSig(sig)}`,
            "```",
            "",
            "_Agency language primitive._",
        ];
        if (sig.description) {
            lines.push("", sig.description);
        }
        return lines.join("\n");
    }
    if (Object.prototype.hasOwnProperty.call(KEYWORD_BUILTIN_HOVERS, name)) {
        const entry = KEYWORD_BUILTIN_HOVERS[name];
        return [
            "```agency",
            entry.sig,
            "```",
            "",
            "_Agency language construct._",
            "",
            entry.description,
        ].join("\n");
    }
    if (Object.prototype.hasOwnProperty.call(JS_GLOBALS, name)) {
        const entry = JS_GLOBALS[name];
        if (entry.kind === "callable") {
            const sigText = entry.sig ? formatSig(entry.sig) : "(any) => any";
            return [
                "```ts",
                `${name}: ${sigText}`,
                "```",
                "",
                "_JavaScript global._",
            ].join("\n");
        }
        // namespace
        const memberNames = Object.keys(entry.members).sort();
        return [
            "```ts",
            `namespace ${name}`,
            "```",
            "",
            "_JavaScript namespace._",
            "",
            `Members: ${memberNames.join(", ")}`,
        ].join("\n");
    }
    return null;
}
/**
 * Hover info for a `<JsNamespace>.<member>` pair (e.g. `JSON.parse`).
 * Returns null if the chain doesn't resolve to a known JS global.
 */
export function lookupJsMemberHover(baseName, memberName) {
    const entry = lookupJsMember([baseName, memberName]);
    if (!entry || entry.kind !== "callable")
        return null;
    const sigText = entry.sig ? formatSig(entry.sig) : "(any) => any";
    return [
        "```ts",
        `${baseName}.${memberName}: ${sigText}`,
        "```",
        "",
        "_JavaScript global._",
    ].join("\n");
}
