/**
 * Multi-source skill path resolver for CAAMP integration.
 * Ported from lib/skills/skill-paths.sh
 *
 * Resolves skills, protocols, and shared resources from multiple locations.
 * Supports CAAMP canonical paths, project-embedded paths, and explicit overrides.
 *
 * Priority order:
 * 1. CLEO_SKILL_PATH entries (explicit overrides, highest priority)
 * 2. Source-determined paths based on CLEO_SKILL_SOURCE
 *
 * @task T4552
 * @epic T4545
 */
import { existsSync, lstatSync, readlinkSync, realpathSync } from 'node:fs';
import { delimiter, join, resolve } from 'node:path';
import { getCanonicalSkillsDir } from '@cleocode/caamp';
/**
 * Get the CAAMP canonical skill location.
 * Delegates to caamp's getCanonicalSkillsDir() which is XDG-aware.
 * @task T4552
 */
function getCaampCanonical() {
    return getCanonicalSkillsDir();
}
/**
 * Get the project-embedded skill location.
 * @task T4552
 */
function getProjectEmbedded(projectRoot) {
    const root = projectRoot ?? process.cwd();
    return join(root, 'skills');
}
/**
 * Get the project root directory.
 * @task T4552
 */
function getProjectRoot(cwd) {
    return cwd ?? process.cwd();
}
/**
 * Safely resolve to a real path.
 * @task T4552
 */
function safeRealpath(path) {
    try {
        return realpathSync(path);
    }
    catch {
        return path;
    }
}
/**
 * Get ordered skill search paths based on configuration.
 *
 * Priority:
 * 1. CLEO_SKILL_PATH entries (colon-separated, explicit overrides)
 * 2. Source-determined paths based on CLEO_SKILL_SOURCE
 *
 * CLEO_SKILL_SOURCE modes:
 * - auto: CAAMP canonical + embedded (default)
 * - caamp: CAAMP canonical only
 * - embedded: Project embedded only
 *
 * @task T4552
 */
export function getSkillSearchPaths(projectRoot) {
    const sourceMode = (process.env['CLEO_SKILL_SOURCE'] ?? 'auto');
    const paths = [];
    // Explicit override paths get highest priority
    const overridePaths = process.env['CLEO_SKILL_PATH'];
    if (overridePaths) {
        for (const p of overridePaths.split(delimiter)) {
            if (p && existsSync(p)) {
                paths.push({ path: p, origin: 'override' });
            }
        }
    }
    const caampDir = getCaampCanonical();
    const embeddedDir = getProjectEmbedded(projectRoot);
    // Source-determined paths
    switch (sourceMode) {
        case 'caamp':
            if (existsSync(caampDir)) {
                paths.push({ path: caampDir, origin: 'caamp' });
            }
            break;
        case 'embedded':
            if (existsSync(embeddedDir)) {
                paths.push({ path: embeddedDir, origin: 'embedded' });
            }
            break;
        default:
            // CAAMP first (external package takes precedence), then embedded
            if (existsSync(caampDir)) {
                paths.push({ path: caampDir, origin: 'caamp' });
            }
            if (existsSync(embeddedDir)) {
                paths.push({ path: embeddedDir, origin: 'embedded' });
            }
            break;
    }
    return paths;
}
/**
 * Resolve a skill directory containing SKILL.md.
 * Searches all paths from getSkillSearchPaths() in priority order.
 * First match wins.
 *
 * @task T4552
 */
export function resolveSkillPath(skillName, projectRoot) {
    const searchPaths = getSkillSearchPaths(projectRoot);
    for (const { path: searchPath } of searchPaths) {
        const candidate = join(searchPath, skillName);
        if (existsSync(join(candidate, 'SKILL.md'))) {
            return safeRealpath(candidate);
        }
    }
    return null;
}
/**
 * Resolve a protocol .md file.
 *
 * Search order:
 * 1. `<core-package>/src/validation/protocols/protocols-markdown/{name}.md`
 *    (canonical location, where the markdown lives in this monorepo)
 * 2. `<base>/protocols/{name}.md` for each registered skill base path
 *    (project-local protocol overrides)
 *
 * @task T4552
 * @task T260 — drop dead Strategy B paths, point at the real protocols-markdown dir
 */
export function resolveProtocolPath(protocolName, projectRoot) {
    // Canonical location in @cleocode/core
    const root = getProjectRoot(projectRoot);
    const canonical = join(root, 'packages', 'core', 'src', 'validation', 'protocols', 'protocols-markdown', `${protocolName}.md`);
    if (existsSync(canonical)) {
        return safeRealpath(canonical);
    }
    // Per-skill-base override directory
    const searchPaths = getSkillSearchPaths(projectRoot);
    for (const { path: searchPath } of searchPaths) {
        const candidate = join(searchPath, 'protocols', `${protocolName}.md`);
        if (existsSync(candidate)) {
            return safeRealpath(candidate);
        }
    }
    return null;
}
/**
 * Resolve a shared resource .md file.
 *
 * Search order per base path: `{base}/_shared/{resource_name}.md`. The
 * `_shared/` directory is the canonical location in `@cleocode/skills`.
 *
 * @task T4552
 * @task T260 — drop dead Strategy B path
 */
export function resolveSharedPath(resourceName, projectRoot) {
    const searchPaths = getSkillSearchPaths(projectRoot);
    for (const { path: searchPath } of searchPaths) {
        const legacy = join(searchPath, '_shared', `${resourceName}.md`);
        if (existsSync(legacy)) {
            return safeRealpath(legacy);
        }
    }
    return null;
}
/**
 * Classify the source of a skill directory.
 *
 * Determines where a skill directory lives in the search hierarchy:
 * - "embedded": Within the project's skills/ directory
 * - "caamp": Within the CAAMP canonical directory (~/.agents/skills)
 * - "project-link": Symlink pointing to project directory
 * - "global-link": Symlink pointing to CAAMP or external location
 *
 * @task T4552
 */
export function getSkillSourceType(skillDir, projectRoot) {
    const normalizedDir = safeRealpath(skillDir);
    const caampDir = safeRealpath(getCaampCanonical());
    const embeddedDir = getProjectEmbedded(projectRoot);
    const root = getProjectRoot(projectRoot);
    // Check if skill_dir is a symlink
    try {
        const stats = lstatSync(skillDir);
        if (stats.isSymbolicLink()) {
            const linkTarget = safeRealpath(readlinkSync(skillDir));
            // Symlink target under CAAMP = global-link
            if (linkTarget.startsWith(caampDir)) {
                return 'global-link';
            }
            // Symlink target under project = project-link
            if (linkTarget.startsWith(embeddedDir) || linkTarget.startsWith(root)) {
                return 'project-link';
            }
            // Symlink to somewhere else
            return 'global-link';
        }
    }
    catch {
        // If lstat fails, continue with directory-based classification
    }
    // Not a symlink - classify by containing directory
    if (normalizedDir.startsWith(resolve(embeddedDir)) ||
        normalizedDir.startsWith(join(root, 'skills'))) {
        return 'embedded';
    }
    if (normalizedDir.startsWith(caampDir)) {
        return 'caamp';
    }
    // Could not classify (likely from explicit CLEO_SKILL_PATH override)
    return null;
}
//# sourceMappingURL=skill-paths.js.map