/**
 * @license
 * Copyright 2026 HopCode Team
 * SPDX-License-Identifier: Apache-2.0
 */
import { mkdirSync, writeFileSync } from 'node:fs';
import { dirname } from 'node:path';
import { writeStdoutLine } from '../../utils/stdioHelpers.js';
import { gitOpt } from './lib/git.js';
function showFile(baseRef, path) {
    return gitOpt('show', `${baseRef}:${path}`);
}
function extractCodeReviewSection(content) {
    // Find `## Code Review` heading and return everything up to the next
    // top-level `## ` heading, or end of file. Done with line-based scanning
    // rather than a regex with `\Z` (which JS doesn't support).
    const lines = content.split('\n');
    let start = -1;
    let end = lines.length;
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (start < 0) {
            if (/^## Code Review\s*$/i.test(line))
                start = i;
        }
        else if (/^## /.test(line)) {
            end = i;
            break;
        }
    }
    if (start < 0)
        return null;
    return lines.slice(start, end).join('\n').trim();
}
function loadCombined(baseRef) {
    const sections = [];
    const loaded = [];
    // 1. HopCode-native rules (preferred), with upstream compat fallback.
    const hopcodeRules = showFile(baseRef, '.hopcode/review-rules.md');
    if (hopcodeRules) {
        sections.push(`### From .hopcode/review-rules.md\n\n${hopcodeRules.trim()}`);
        loaded.push('.hopcode/review-rules.md');
    }
    else {
        const hopcodeRules = showFile(baseRef, '.hopcode/review-rules.md');
        if (hopcodeRules) {
            sections.push(`### From .hopcode/review-rules.md\n\n${hopcodeRules.trim()}`);
            loaded.push('.hopcode/review-rules.md');
        }
    }
    // 2. Copilot-compatible rules: prefer .github/copilot-instructions.md;
    //    only fall back to root-level copilot-instructions.md if the
    //    preferred one doesn't exist on the base branch.
    const copilotPreferred = showFile(baseRef, '.github/copilot-instructions.md');
    if (copilotPreferred) {
        sections.push(`### From .github/copilot-instructions.md\n\n${copilotPreferred.trim()}`);
        loaded.push('.github/copilot-instructions.md');
    }
    else {
        const copilotFallback = showFile(baseRef, 'copilot-instructions.md');
        if (copilotFallback) {
            sections.push(`### From copilot-instructions.md\n\n${copilotFallback.trim()}`);
            loaded.push('copilot-instructions.md');
        }
    }
    // 3. AGENTS.md — extract Code Review section only.
    const agentsMd = showFile(baseRef, 'AGENTS.md');
    if (agentsMd) {
        const section = extractCodeReviewSection(agentsMd);
        if (section) {
            sections.push(`### From AGENTS.md\n\n${section}`);
            loaded.push('AGENTS.md');
        }
    }
    // 4. HOPCODE.md — extract Code Review section only.
    const hopcodeMd = showFile(baseRef, 'HOPCODE.md');
    if (hopcodeMd) {
        const section = extractCodeReviewSection(hopcodeMd);
        if (section) {
            sections.push(`### From HOPCODE.md\n\n${section}`);
            loaded.push('HOPCODE.md');
        }
    }
    return {
        combined: sections.join('\n\n---\n\n'),
        loaded,
    };
}
async function runLoadRules(args) {
    const { base_ref: baseRef, out } = args;
    const { combined, loaded } = loadCombined(baseRef);
    mkdirSync(dirname(out), { recursive: true });
    writeFileSync(out, combined, 'utf8');
    if (loaded.length === 0) {
        writeStdoutLine(`No review rules found on ${baseRef}; wrote empty file to ${out}`);
    }
    else {
        writeStdoutLine(`Loaded ${loaded.length} rule source(s) from ${baseRef} → ${out}: ${loaded.join(', ')}`);
    }
}
export const loadRulesCommand = {
    command: 'load-rules <base_ref>',
    describe: 'Read project review rules from the base branch (.hopcode/review-rules.md, .hopcode/review-rules.md, .github/copilot-instructions.md, AGENTS.md, HOPCODE.md) and write a combined Markdown file',
    builder: (yargs) => yargs
        .positional('base_ref', {
        type: 'string',
        demandOption: true,
        describe: 'Base ref to read rules from — typically the PR base branch (e.g. "origin/main"). Loading from the base branch (not the PR branch) prevents a malicious PR from injecting bypass rules.',
    })
        .option('out', {
        type: 'string',
        demandOption: true,
        describe: 'Output Markdown path (will be overwritten — empty if no rules found)',
    }),
    handler: async (argv) => {
        await runLoadRules(argv);
    },
};
//# sourceMappingURL=load-rules.js.map