import { createHash } from 'node:crypto';
import TOML from '@iarna/toml';
export const OAT_MANAGED_ROLE_HEADER = '# oat-managed: true';
export const OAT_MANAGED_ROLE_NAME_PREFIX = '# oat-role: ';
export const OAT_MANAGED_ROLE_OWNER_PREFIX = '# oat-owner: ';
const CODEX_ROLE_MARKER_PATTERN = /^# oat-role: ([a-zA-Z0-9_-]+)$/;
const CODEX_OWNER_MARKER_PATTERN = /^# oat-owner: (supported-catalogue|user-config|project-config)$/;
const STANDARD_SUPPORTED_CODEX_EFFORTS = [
    'low',
    'medium',
    'high',
    'xhigh',
];
export const SUPPORTED_CODEX_ROLE_TARGETS = [
    ...STANDARD_SUPPORTED_CODEX_EFFORTS.map((effort) => ({
        model: 'gpt-5.6-luna',
        effort,
    })),
    ...STANDARD_SUPPORTED_CODEX_EFFORTS.map((effort) => ({
        model: 'gpt-5.6-terra',
        effort,
    })),
    ...[...STANDARD_SUPPORTED_CODEX_EFFORTS, 'max'].map((effort) => ({
        model: 'gpt-5.6-sol',
        effort,
    })),
];
export function sanitizeCodexRoleName(input) {
    return normalizeCodexRoleName(input.replace(/\.md$/i, ''));
}
export function normalizeCodexRoleName(input) {
    return input
        .trim()
        .toLowerCase()
        .replace(/[^a-z0-9_-]+/g, '-')
        .replace(/-{2,}/g, '-')
        .replace(/^-+|-+$/g, '');
}
function isSupportedCodexRoleTarget(model, effort) {
    return SUPPORTED_CODEX_ROLE_TARGETS.some((supported) => supported.model === model && supported.effort === effort);
}
export function buildCodexMaterializedTargetRoleName(options) {
    const normalizedAgentName = sanitizeCodexRoleName(options.agentName);
    const normalizedModel = normalizeCodexRoleName(options.model);
    const normalizedEffort = normalizeCodexRoleName(options.effort);
    const customTargetSuffix = isSupportedCodexRoleTarget(options.model, options.effort)
        ? ''
        : `-${createHash('sha256')
            .update(`${options.model}\0${options.effort}`)
            .digest('hex')
            .slice(0, 10)}`;
    return normalizeCodexRoleName(`${normalizedAgentName}-${normalizedModel}-${normalizedEffort}${customTargetSuffix}`);
}
function parseOatManagedCodexRoleHeader(content) {
    const lines = content
        .split('\n')
        .map((line) => (line.endsWith('\r') ? line.slice(0, -1) : line));
    const headerLines = [];
    for (const line of lines) {
        if (!line.startsWith('# oat-')) {
            break;
        }
        headerLines.push(line);
    }
    if (headerLines.length < 2 ||
        headerLines.length > 3 ||
        headerLines[0] !== OAT_MANAGED_ROLE_HEADER) {
        return null;
    }
    const roleMatch = CODEX_ROLE_MARKER_PATTERN.exec(headerLines[1]);
    if (!roleMatch) {
        return null;
    }
    let owner = null;
    let ownerLineIndex = null;
    if (headerLines.length === 3) {
        const ownerMatch = CODEX_OWNER_MARKER_PATTERN.exec(headerLines[2]);
        if (!ownerMatch) {
            return null;
        }
        owner = ownerMatch[1];
        ownerLineIndex = 2;
    }
    return {
        roleName: roleMatch[1],
        roleLineIndex: 1,
        owner,
        ownerLineIndex,
    };
}
export function isOatManagedCodexRoleFile(content, roleName) {
    const header = parseOatManagedCodexRoleHeader(content);
    if (!header) {
        return false;
    }
    return roleName === undefined || header.roleName === roleName;
}
export function withOatManagedCodexHeader(roleName, tomlBody) {
    return `${OAT_MANAGED_ROLE_HEADER}\n${OAT_MANAGED_ROLE_NAME_PREFIX}${roleName}\n${tomlBody}`;
}
export function readOatManagedCodexRoleOwner(content) {
    return parseOatManagedCodexRoleHeader(content)?.owner ?? null;
}
export function withOatManagedCodexRoleOwner(content, owner) {
    const header = parseOatManagedCodexRoleHeader(content);
    if (!header) {
        return content;
    }
    const lines = content.split('\n');
    const ownerLine = `${OAT_MANAGED_ROLE_OWNER_PREFIX}${owner}`;
    const usesCarriageReturn = lines[header.roleLineIndex]?.endsWith('\r') ?? false;
    const encodedOwnerLine = `${ownerLine}${usesCarriageReturn ? '\r' : ''}`;
    if (header.ownerLineIndex !== null) {
        lines[header.ownerLineIndex] = encodedOwnerLine;
        return lines.join('\n');
    }
    lines.splice(header.roleLineIndex + 1, 0, encodedOwnerLine);
    return lines.join('\n');
}
export function stringifyToml(object) {
    return TOML.stringify(object);
}
