import { YamlStore } from "./yaml-store.js";
import { THINKING_LEVELS as SHARED_THINKING_LEVELS, isKnownThinkingLevel } from "../../shared/thinking-levels.js";
/** Normalize legacy grant policy values to the new three-value set. */
export function normalizeGrantPolicy(value) {
    switch (value) {
        case 'always-allow': return 'allow';
        case 'ask-once': return 'ask';
        case 'always-ask': return 'ask';
        case 'never-ask': return 'never';
        case 'allow': return 'allow';
        case 'ask': return 'ask';
        case 'never': return 'never';
        default: return 'allow';
    }
}
/** Check if a value is a valid grant policy (old or new). */
function isGrantPolicyValue(value) {
    return typeof value === 'string' && ['allow', 'ask', 'never', 'always-allow', 'ask-once', 'always-ask', 'never-ask'].includes(value);
}
/** Normalize all values in a toolPolicies record. */
function normalizeToolPolicies(policies) {
    if (!policies || typeof policies !== 'object')
        return undefined;
    const result = {};
    for (const [key, value] of Object.entries(policies)) {
        if (isGrantPolicyValue(value)) {
            result[key] = normalizeGrantPolicy(value);
        }
    }
    return Object.keys(result).length > 0 ? result : undefined;
}
/**
 * Valid thinking level values. Re-exports the shared canonical set so callers
 * that import from role-store keep a stable path. The shared module is the
 * single source of truth — extending the set requires touching one place.
 */
export const VALID_THINKING_LEVELS = SHARED_THINKING_LEVELS;
/**
 * Validate a model string. Accepts only "<provider>/<modelId>" with non-empty
 * parts on each side of the slash. Empty strings, whitespace-only, or malformed
 * values are silently dropped (returns `undefined`) to avoid breaking role
 * loading on bad input.
 */
export function validateModelString(value) {
    if (typeof value !== "string")
        return undefined;
    const trimmed = value.trim();
    if (!trimmed)
        return undefined;
    const slash = trimmed.indexOf("/");
    if (slash <= 0 || slash >= trimmed.length - 1)
        return undefined;
    return trimmed;
}
/**
 * Validate a thinking-level string. Accepts only the canonical set
 * (off, minimal, low, medium, high, xhigh). Unknown values are silently
 * dropped. Clamping against a specific model happens at use-time via
 * `clampThinkingLevel` from `src/shared/thinking-levels.ts`.
 */
export function validateThinkingLevel(value) {
    return isKnownThinkingLevel(value);
}
function parseRole(data) {
    if (!data.name)
        return null;
    return {
        name: data.name,
        label: data.label ?? data.name,
        promptTemplate: data.promptTemplate ?? "",
        accessory: data.accessory ?? "none",
        toolPolicies: normalizeToolPolicies(data.toolPolicies),
        model: validateModelString(data.model),
        thinkingLevel: validateThinkingLevel(data.thinkingLevel),
        createdAt: data.createdAt ?? 0,
        updatedAt: data.updatedAt ?? 0,
    };
}
function serializeRole(role) {
    const obj = {
        name: role.name,
        label: role.label,
        accessory: role.accessory,
    };
    if (role.toolPolicies && Object.keys(role.toolPolicies).length > 0) {
        obj.toolPolicies = role.toolPolicies;
    }
    if (role.model)
        obj.model = role.model;
    if (role.thinkingLevel)
        obj.thinkingLevel = role.thinkingLevel;
    obj.createdAt = role.createdAt;
    obj.updatedAt = role.updatedAt;
    obj.promptTemplate = role.promptTemplate;
    return obj;
}
/**
 * File-backed role store with builtin cascade support.
 * Each role is a YAML file in roles/<name>.yaml.
 */
export class RoleStore extends YamlStore {
    constructor(configDir) {
        super(configDir, {
            subdir: "roles",
            keyFn: r => r.name,
            parseItem: parseRole,
            serializeItem: serializeRole,
            logPrefix: "[role-store]",
        });
    }
    /** Override put to normalize legacy tool policies before saving. */
    put(role) {
        if (role.toolPolicies) {
            role.toolPolicies = normalizeToolPolicies(role.toolPolicies) ?? {};
        }
        // Re-validate model/thinking on write so callers can't smuggle malformed values past the API layer.
        if (role.model !== undefined)
            role.model = validateModelString(role.model);
        if (role.thinkingLevel !== undefined)
            role.thinkingLevel = validateThinkingLevel(role.thinkingLevel);
        super.put(role);
    }
}
//# sourceMappingURL=role-store.js.map