"use strict";
// src/orchestrator/story/StoryStateTracker.ts
// v1.17.0 — Atomic mutations of a `*.story.md` file. Drives:
//   - AC checkbox toggling at index
//   - Dev Agent Record append (per-iteration entries)
//   - File List append
//   - Status transition (delegates to StoryWriter + StoryLifecycle)
//
// All writes go through writeStringAtomic so a crash mid-write
// can never leave a half-written story file.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkAC = checkAC;
exports.appendDevAgentRecord = appendDevAgentRecord;
exports.appendFileList = appendFileList;
exports.transitionStatus = transitionStatus;
exports.countOpenACs = countOpenACs;
exports.countTotalACs = countTotalACs;
const fs = __importStar(require("fs"));
const AtomicWriter_1 = require("../util/AtomicWriter");
const StoryLifecycle_1 = require("./StoryLifecycle");
const StoryWriter_1 = require("./StoryWriter");
const AC_CHECKBOX_RE = /^(\s*(?:[-*]|\d+\.))\s*\[([ xX])\]\s+/;
const DEV_AGENT_HEADING_RE = /^##\s+Dev Agent Record\s*$/m;
const FILE_LIST_HEADING_RE = /^##\s+File List\s*$/m;
function checkAC(storyPath, idx) {
    const content = fs.readFileSync(storyPath, 'utf-8');
    const lines = content.split('\n');
    let acCount = 0;
    let mutated = false;
    for (let i = 0; i < lines.length; i++) {
        const m = AC_CHECKBOX_RE.exec(lines[i]);
        if (!m)
            continue;
        if (acCount === idx) {
            if (m[2] === ' ') {
                lines[i] = lines[i].replace(AC_CHECKBOX_RE, `${m[1]} [x] `);
                mutated = true;
            }
            else {
                return true;
            }
            break;
        }
        acCount++;
    }
    if (!mutated)
        return acCount > idx;
    (0, AtomicWriter_1.writeStringAtomic)(storyPath, lines.join('\n'));
    return true;
}
function appendDevAgentRecord(storyPath, entry) {
    const content = fs.readFileSync(storyPath, 'utf-8');
    const block = renderDevAgentBlock(entry);
    let updated;
    if (DEV_AGENT_HEADING_RE.test(content)) {
        if (content.endsWith('\n')) {
            updated = `${content}${block}\n`;
        }
        else {
            updated = `${content}\n${block}\n`;
        }
    }
    else {
        const sep = content.endsWith('\n') ? '' : '\n';
        updated = `${content}${sep}\n## Dev Agent Record\n\n${block}\n`;
    }
    (0, AtomicWriter_1.writeStringAtomic)(storyPath, updated);
}
function renderDevAgentBlock(entry) {
    const lines = [`### Iteration ${entry.iter} — ${entry.persona}`];
    lines.push('');
    lines.push(entry.summary);
    if (entry.test_cmd) {
        lines.push('');
        lines.push(`**Test:** \`${entry.test_cmd}\` — ${entry.test_passed ? '✓ pass' : '✗ fail'}`);
    }
    if (typeof entry.duration_ms === 'number') {
        lines.push('');
        lines.push(`_Duration: ${(entry.duration_ms / 1000).toFixed(1)}s_`);
    }
    return lines.join('\n');
}
function appendFileList(storyPath, paths) {
    if (paths.length === 0)
        return;
    const content = fs.readFileSync(storyPath, 'utf-8');
    const existing = new Set();
    const headingMatch = FILE_LIST_HEADING_RE.exec(content);
    if (headingMatch) {
        const after = content.slice((headingMatch.index || 0) + headingMatch[0].length);
        const sectionEnd = after.match(/^##\s+/m);
        const section = sectionEnd ? after.slice(0, sectionEnd.index) : after;
        for (const line of section.split('\n')) {
            const m = /^\s*-\s+(.+)$/.exec(line);
            if (m)
                existing.add(m[1].trim());
        }
    }
    const toAdd = paths.filter(p => !existing.has(p));
    if (toAdd.length === 0)
        return;
    const block = toAdd.map(p => `- ${p}`).join('\n');
    let updated;
    if (headingMatch) {
        const after = content.slice((headingMatch.index || 0) + headingMatch[0].length);
        const sectionEnd = after.match(/^##\s+/m);
        if (sectionEnd) {
            const cut = (headingMatch.index || 0) + headingMatch[0].length + (sectionEnd.index || 0);
            const before = content.slice(0, cut).replace(/\s*$/, '\n');
            const rest = content.slice(cut);
            updated = `${before}${block}\n\n${rest}`;
        }
        else {
            const sep = content.endsWith('\n') ? '' : '\n';
            updated = `${content}${sep}${block}\n`;
        }
    }
    else {
        const sep = content.endsWith('\n') ? '' : '\n';
        updated = `${content}${sep}\n## File List\n\n${block}\n`;
    }
    (0, AtomicWriter_1.writeStringAtomic)(storyPath, updated);
}
function transitionStatus(storyPath, current, next, roleOverride) {
    const role = (0, StoryLifecycle_1.currentRole)(roleOverride);
    const decision = (0, StoryLifecycle_1.canTransition)(current, next, role);
    if (!decision.allowed) {
        return { ok: false, error: `transition_forbidden: ${current}->${next} as role=${role} — ${decision.reason}` };
    }
    try {
        (0, StoryWriter_1.updateStoryStatus)(storyPath, current, next, {
            author: role,
            note: `Autonomous loop transition (StoryStateTracker)`,
        });
        return { ok: true };
    }
    catch (err) {
        return { ok: false, error: err instanceof Error ? err.message : String(err) };
    }
}
function countOpenACs(storyPath) {
    const content = fs.readFileSync(storyPath, 'utf-8');
    let count = 0;
    for (const line of content.split('\n')) {
        const m = AC_CHECKBOX_RE.exec(line);
        if (m && m[2] === ' ')
            count++;
    }
    return count;
}
function countTotalACs(storyPath) {
    const content = fs.readFileSync(storyPath, 'utf-8');
    let count = 0;
    for (const line of content.split('\n')) {
        if (AC_CHECKBOX_RE.exec(line))
            count++;
    }
    return count;
}
