#!/usr/bin/env node
// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only
import { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
import path, { join } from 'node:path';
import { createWUParser, WU_OPTIONS } from '@lumenflow/core/arg-parser';
import { getConfig } from '@lumenflow/core/config';
import { canonicalizeInitiativeId, initiativeIdRegex, loadInitiativeIdConfig, } from '@lumenflow/core';
import { die } from '@lumenflow/core/error-handler';
import { parseYAML, stringifyYAML } from '@lumenflow/core/wu-yaml';
import { ensureOnMain } from '@lumenflow/core/wu-helpers';
import { getGitForCwd } from '@lumenflow/core/git-adapter';
import { withMicroWorktree } from '@lumenflow/core/micro-worktree';
import { runCLI } from './cli-entry-point.js';
const PREFIX = '[initiative:delete]';
const OPERATION = 'initiative-delete';
function readYamlObject(filePath) {
    const raw = readFileSync(filePath, 'utf-8');
    const parsed = parseYAML(raw);
    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
        throw new Error(`${PREFIX} Invalid YAML object: ${filePath}`);
    }
    return parsed;
}
function resolveConfiguredDir(worktreePath, configuredRelativePath, fallbackRelativePath) {
    const configuredAbsolute = join(worktreePath, configuredRelativePath);
    if (existsSync(configuredAbsolute)) {
        return configuredRelativePath;
    }
    const fallbackAbsolute = join(worktreePath, fallbackRelativePath);
    if (existsSync(fallbackAbsolute)) {
        return fallbackRelativePath;
    }
    return configuredRelativePath;
}
function canonicalizeInitiativeLifecycleId(id, projectRoot) {
    const config = loadInitiativeIdConfig({ projectRoot });
    const canonical = canonicalizeInitiativeId(id, config);
    if (canonical) {
        return canonical;
    }
    if (initiativeIdRegex(config).test(id)) {
        return id;
    }
    throw new Error(`${PREFIX} Invalid initiative ID: ${id}`);
}
function listLinkedWus(worktreePath, initId) {
    const wuDir = join(worktreePath, resolveConfiguredDir(worktreePath, getConfig({ projectRoot: worktreePath }).directories.wuDir, 'docs/operations/tasks/wu'));
    if (!existsSync(wuDir)) {
        return [];
    }
    const linked = new Set();
    for (const fileName of readdirSync(wuDir)) {
        if (!fileName.endsWith('.yaml')) {
            continue;
        }
        const filePath = path.join(wuDir, fileName);
        const doc = readYamlObject(filePath);
        if (doc.initiative === initId && typeof doc.id === 'string') {
            linked.add(doc.id);
        }
    }
    return [...linked];
}
export function validateInitiativeDelete(input) {
    if (input.linkedWus.length > 0 && !input.force) {
        throw new Error(`${PREFIX} Cannot delete ${input.initId}: linked WUs exist (${input.linkedWus.join(', ')}). Re-run with --force to unlink them explicitly.`);
    }
}
function unlinkWuInitiativeRefs(worktreePath, initId) {
    const wuDir = join(worktreePath, resolveConfiguredDir(worktreePath, getConfig({ projectRoot: worktreePath }).directories.wuDir, 'docs/operations/tasks/wu'));
    if (!existsSync(wuDir)) {
        return [];
    }
    const touched = [];
    for (const fileName of readdirSync(wuDir)) {
        if (!fileName.endsWith('.yaml')) {
            continue;
        }
        const filePath = path.join(wuDir, fileName);
        const doc = readYamlObject(filePath);
        if (doc.initiative !== initId) {
            continue;
        }
        delete doc.initiative;
        writeFileSync(filePath, stringifyYAML(doc), 'utf-8');
        touched.push(filePath);
    }
    return touched;
}
export function deleteInitiativeInWorktree(input) {
    const initiativesDir = resolveConfiguredDir(input.worktreePath, getConfig({ projectRoot: input.worktreePath }).directories.initiativesDir, 'docs/operations/tasks/initiatives');
    const initPath = join(input.worktreePath, initiativesDir, `${input.initId}.yaml`);
    if (!existsSync(initPath)) {
        throw new Error(`${PREFIX} Initiative not found: ${input.initId}`);
    }
    const linkedWus = listLinkedWus(input.worktreePath, input.initId);
    validateInitiativeDelete({
        initId: input.initId,
        linkedWus,
        force: input.force,
    });
    const touched = input.force ? unlinkWuInitiativeRefs(input.worktreePath, input.initId) : [];
    unlinkSync(initPath);
    return { filesTouched: [initPath, ...touched] };
}
async function ensureCleanWorkingTree() {
    const status = await getGitForCwd().getStatus();
    if (status.trim()) {
        die(`Working tree is not clean. Cannot delete initiative.\n\nUncommitted changes:\n${status}\n`);
    }
}
export async function main() {
    const args = createWUParser({
        name: 'initiative-delete',
        description: 'Delete an initiative with explicit linked-WU safeguards',
        options: [WU_OPTIONS.id, WU_OPTIONS.force],
        required: ['id'],
        allowPositionalId: true,
    });
    const initId = canonicalizeInitiativeLifecycleId(args.id, process.cwd());
    await ensureOnMain(getGitForCwd());
    await ensureCleanWorkingTree();
    await withMicroWorktree({
        operation: OPERATION,
        id: initId,
        logPrefix: PREFIX,
        pushOnly: true,
        execute: async ({ worktreePath }) => {
            const result = deleteInitiativeInWorktree({
                worktreePath,
                initId,
                force: Boolean(args.force),
            });
            return {
                commitMessage: `docs: delete ${initId.toLowerCase()}`,
                files: result.filesTouched.map((filePath) => path.relative(worktreePath, filePath)),
            };
        },
    });
    console.log(`${PREFIX} Deleted ${initId}`);
}
if (import.meta.main) {
    void runCLI(main);
}
//# sourceMappingURL=initiative-delete.js.map