/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { existsSync } from 'node:fs';
import { homedir } from 'node:os';
import { join } from 'node:path';
import { getTargetPath, loadRegistry, renderForTarget } from '../services/rule-registry.js';
import { generateAutonomousPreFlight, generateBaseGuidelines, generateSfStandards, generateSubAgentProtocol, } from '../generators/mdc-generator.js';
import { BACKLOG_SYNC_PROFILES, CODE_ANALYZER_PROFILES, DEPLOY_PROFILES, ELEMENTS_SYNC_PROFILES, PROMPT_REGISTRY_PROFILES, QA_EVIDENCE_PROFILES, STORY_MAP_PROFILES, generateBacklogSyncSkill, generateCodeAnalyzerSkill, generateDeploySkill, generateDiagramExportSkill, generateElementsSyncSkill, generatePromptRegistrySkill, generateQaEvidencePackSkill, generateStoryMappingSkill, getReferenceFiles, } from '../generators/skill-generator.js';
import { ensureDir } from '../services/file-writer.js';
import { PLUGIN_VERSION } from '../version.js';
export async function setupCursor(opts) {
    const { cwd, profiles, writer, isSalesforceProject, ruleOverrides, promptScope, logInfo } = opts;
    const projectRulesDir = join(cwd, '.cursor', 'rules');
    ensureDir(projectRulesDir);
    writer.write(join(projectRulesDir, 'agent-guidelines.mdc'), generateBaseGuidelines(PLUGIN_VERSION));
    writer.write(join(projectRulesDir, 'setup-agents-autonomous.mdc'), generateAutonomousPreFlight(PLUGIN_VERSION));
    writer.write(join(projectRulesDir, 'sub-agent-protocol.mdc'), generateSubAgentProtocol(profiles, PLUGIN_VERSION));
    if (isSalesforceProject) {
        const scope = await promptScope();
        const targetRulesDir = scope === 'user' ? join(homedir(), '.cursor', 'rules') : projectRulesDir;
        if (scope === 'user') {
            ensureDir(targetRulesDir);
            logInfo(`Writing Salesforce rules to user-level directory: ${targetRulesDir}`);
        }
        writer.write(join(targetRulesDir, 'salesforce-standards.mdc'), generateSfStandards(PLUGIN_VERSION));
        for (const profile of profiles) {
            const content = applyCursorScope(injectPluginVersion(profile.ruleContent(), PLUGIN_VERSION), profile, ruleOverrides?.[profile.id]);
            writer.write(join(targetRulesDir, profile.ruleFile), content);
        }
        setupWorkflows(cwd, profiles, writer);
    }
    else {
        for (const profile of profiles) {
            const content = applyCursorScope(injectPluginVersion(profile.ruleContent(), PLUGIN_VERSION), profile, ruleOverrides?.[profile.id]);
            writer.write(join(projectRulesDir, profile.ruleFile), content);
        }
    }
    setupSkills(cwd, profiles, writer);
    injectRegistryRules(cwd, writer);
}
/** Injects any neutral rules from .setup-agents/rules/ into Cursor format (backward-compatible no-op if empty). */
function injectRegistryRules(cwd, writer) {
    const rules = loadRegistry(cwd);
    for (const rule of rules) {
        const rendered = renderForTarget(rule, 'cursor');
        const targetPath = getTargetPath(cwd, rule, 'cursor');
        writer.write(targetPath, rendered);
    }
}
function setupWorkflows(cwd, profiles, writer) {
    const workflowsDir = join(cwd, '.a4drules', 'workflows');
    if (!existsSync(workflowsDir)) {
        return;
    }
    for (const profile of profiles) {
        if (!profile.workflows)
            continue;
        const workflowFiles = profile.workflows(PLUGIN_VERSION);
        for (const [filename, content] of Object.entries(workflowFiles)) {
            writer.write(join(workflowsDir, filename), content);
        }
    }
}
const SKILL_REGISTRY = [
    { profileSet: DEPLOY_PROFILES, dirName: 'sf-deploy', generator: generateDeploySkill },
    { profileSet: CODE_ANALYZER_PROFILES, dirName: 'sf-code-analyzer', generator: generateCodeAnalyzerSkill },
    { profileSet: BACKLOG_SYNC_PROFILES, dirName: 'backlog-sync', generator: generateBacklogSyncSkill },
    { profileSet: ELEMENTS_SYNC_PROFILES, dirName: 'elements-sync', generator: generateElementsSyncSkill },
    { profileSet: PROMPT_REGISTRY_PROFILES, dirName: 'prompt-registry', generator: generatePromptRegistrySkill },
    { profileSet: QA_EVIDENCE_PROFILES, dirName: 'qa-evidence-pack', generator: generateQaEvidencePackSkill },
];
function setupSkills(cwd, profiles, writer) {
    const profileIds = new Set(profiles.map((p) => p.id));
    const skillsDir = join(cwd, '.cursor', 'skills');
    const needsStoryMap = [...profileIds].some((id) => STORY_MAP_PROFILES.has(id));
    const matchedSkills = SKILL_REGISTRY.filter((s) => [...profileIds].some((id) => s.profileSet.has(id)));
    if (!needsStoryMap && matchedSkills.length === 0)
        return;
    ensureDir(skillsDir);
    if (needsStoryMap) {
        writeStoryMapSkills(skillsDir, writer);
    }
    for (const skill of matchedSkills) {
        writeSkill(skillsDir, skill.dirName, skill.generator(), writer);
    }
    writeReferenceFiles(cwd, profileIds, writer);
}
function writeStoryMapSkills(skillsDir, writer) {
    for (const [dirName, generator] of [
        ['story-mapping', generateStoryMappingSkill],
        ['diagram-export', generateDiagramExportSkill],
    ]) {
        writeSkill(skillsDir, dirName, generator(), writer);
    }
}
function writeReferenceFiles(cwd, profileIds, writer) {
    const refsDir = join(cwd, '.setup-agents', 'references');
    const refs = getReferenceFiles([...profileIds]);
    if (Object.keys(refs).length === 0)
        return;
    ensureDir(refsDir);
    for (const [relativePath, content] of Object.entries(refs)) {
        writer.write(join(refsDir, relativePath), content);
    }
}
function injectPluginVersion(content, version) {
    // Insert pluginVersion into the YAML frontmatter so findStaleFiles can detect outdated files.
    return content.replace(/^(---\n(?:.*\n)*?)(---)/m, `$1pluginVersion: "${version}"\n$2`);
}
function applyCursorScope(content, profile, override) {
    const scope = override?.scope ?? profile.cursorScope ?? 'always';
    const globs = override?.globs ?? profile.globs;
    const globsLine = scope === 'auto-attach' && globs?.length ? `globs: ${globs.join(', ')}` : 'globs:';
    const alwaysApply = scope === 'always' ? 'alwaysApply: true' : 'alwaysApply: false';
    return content.replace(/^globs:.*$/m, globsLine).replace(/^alwaysApply:.*$/m, alwaysApply);
}
function writeSkill(skillsDir, dirName, files, writer) {
    const dir = join(skillsDir, dirName);
    for (const [relativePath, content] of Object.entries(files)) {
        const fullPath = join(dir, relativePath);
        ensureDir(join(fullPath, '..'));
        writer.write(fullPath, content);
    }
}
//# sourceMappingURL=cursor-setup.js.map