#!/usr/bin/env node
/**
 * v17.0.0 substrate migration entrypoint.
 *
 * Retired readers and translation logic belong under scripts/migrations,
 * not in shipped runtime code under src/.
 *
 * Usage:
 *   npm run upgrade -- --graph <name> [--repo <path>] [--dry-run] [--json]
 */
import process from 'node:process';
import NodeCryptoAdapter from "../../../src/infrastructure/adapters/NodeCryptoAdapter.js";
import { createPersistence, resolveGraphName } from "../../../bin/cli/shared.js";
import { upgradeCheckpointSchema, } from "./checkpoint-schema-upgrade.js";
class MigrationCliArgumentError extends Error {
    constructor(message) {
        super(message);
        this.name = 'MigrationCliArgumentError';
    }
}
class MigrationCliArgs {
    repo;
    graph;
    dryRun;
    json;
    help;
    constructor(repo, graph, dryRun, json, help) {
        this.repo = repo;
        this.graph = graph;
        this.dryRun = dryRun;
        this.json = json;
        this.help = help;
        Object.freeze(this);
    }
}
function usage() {
    return [
        'Usage:',
        '  npm run upgrade -- --graph <name> [--repo <path>] [--dry-run] [--json]',
        '',
        'Options:',
        '  --graph <name>  Graph name to upgrade. Required unless exactly one graph exists.',
        '  --repo <path>   Git repository path. Defaults to the current working directory.',
        '  --dry-run       Read and validate retired checkpoints without moving refs.',
        '  --json          Emit machine-readable JSON.',
        '  --help          Show this help.',
    ].join('\n');
}
function parseArgs(argv) {
    let repo = process.cwd();
    let graph = null;
    let dryRun = false;
    let json = false;
    let help = false;
    for (let i = 0; i < argv.length; i++) {
        const arg = argv[i];
        if (arg === '--repo') {
            const value = argv[i + 1];
            if (value === undefined) {
                throw new MigrationCliArgumentError('--repo requires a path');
            }
            repo = value;
            i++;
            continue;
        }
        if (arg === '--graph') {
            const value = argv[i + 1];
            if (value === undefined) {
                throw new MigrationCliArgumentError('--graph requires a graph name');
            }
            graph = value;
            i++;
            continue;
        }
        if (arg === '--dry-run') {
            dryRun = true;
            continue;
        }
        if (arg === '--json') {
            json = true;
            continue;
        }
        if (arg === '--help' || arg === '-h') {
            help = true;
            continue;
        }
        throw new MigrationCliArgumentError(`Unknown argument: ${arg ?? ''}`);
    }
    return new MigrationCliArgs(repo, graph, dryRun, json, help);
}
function formatHumanResult(result) {
    if (result.status === 'missing-checkpoint') {
        return `No checkpoint found for graph ${result.graphName}; nothing to upgrade.`;
    }
    if (result.status === 'already-current') {
        return `Checkpoint ${result.previousCheckpointSha ?? '(none)'} is already schema:${result.currentSchema}.`;
    }
    if (result.status === 'would-upgrade') {
        return [
            `Dry run: checkpoint ${result.previousCheckpointSha ?? '(none)'} can be upgraded.`,
            `Would write schema:${result.currentSchema} checkpoint and leave ${result.checkpointRef} unchanged.`,
        ].join('\n');
    }
    return [
        `Upgraded graph ${result.graphName} checkpoint.`,
        `Previous: ${result.previousCheckpointSha ?? '(none)'} schema:${String(result.previousSchema)}`,
        `Current:  ${result.upgradedCheckpointSha ?? '(none)'} schema:${result.currentSchema}`,
        `Updated:  ${result.checkpointRef}`,
    ].join('\n');
}
async function run() {
    const args = parseArgs(process.argv.slice(2));
    if (args.help) {
        process.stdout.write(`${usage()}\n`);
        return;
    }
    const { persistence } = await createPersistence(args.repo);
    const graphName = await resolveGraphName(persistence, args.graph);
    const result = await upgradeCheckpointSchema({
        persistence,
        graphName,
        dryRun: args.dryRun,
        crypto: new NodeCryptoAdapter(),
    });
    if (args.json) {
        process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
        return;
    }
    process.stdout.write(`${formatHumanResult(result)}\n`);
}
function errorMessage(err) {
    return err instanceof Error ? err.message : String(err);
}
run().catch((err) => {
    const message = errorMessage(err);
    process.stderr.write(`${message}\n\n${usage()}\n`);
    process.exitCode = 1;
});
