"use strict";
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.run = run;
const child_process_1 = require("child_process");
const net = __importStar(require("net"));
const path = __importStar(require("path"));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { version: currentVersion } = require('../../package.json');
const PKG = '@doquflow/cli';
const DEFAULT_PORT = 48821;
function fetchLatestVersion() {
    try {
        const out = (0, child_process_1.execSync)(`npm view ${PKG} version`, { stdio: ['ignore', 'pipe', 'pipe'] })
            .toString()
            .trim();
        if (!/^\d+\.\d+\.\d+/.test(out))
            throw new Error(`unexpected npm output: ${out}`);
        return out;
    }
    catch (e) {
        throw new Error(`Could not fetch latest version from npm registry: ${e.message}`);
    }
}
function compareSemver(a, b) {
    const pa = a.split('.').map(n => parseInt(n, 10));
    const pb = b.split('.').map(n => parseInt(n, 10));
    for (let i = 0; i < 3; i++) {
        if ((pa[i] ?? 0) > (pb[i] ?? 0))
            return 1;
        if ((pa[i] ?? 0) < (pb[i] ?? 0))
            return -1;
    }
    return 0;
}
function isPortInUse(port) {
    return new Promise(resolve => {
        const sock = net.createConnection({ port, host: '127.0.0.1' });
        sock.once('connect', () => { sock.end(); resolve(true); });
        sock.once('error', () => resolve(false));
    });
}
async function run(opts = {}) {
    console.log(`DocuFlow update`);
    console.log(`  Current: ${currentVersion}`);
    let latest;
    try {
        latest = fetchLatestVersion();
    }
    catch (e) {
        console.error(`✗ ${e.message}`);
        process.exit(1);
    }
    console.log(`  Latest:  ${latest}`);
    const cmp = compareSemver(latest, currentVersion);
    if (opts.check) {
        if (cmp > 0)
            console.log(`\n→ Update available. Run \`docuflow update\` to install.`);
        else
            console.log(`\n✓ You are on the latest version.`);
        return;
    }
    if (cmp <= 0 && !opts.force) {
        console.log(`\n✓ Already on the latest version. Use --force to reinstall.`);
        return;
    }
    // Derive the global prefix from the node binary that is running this CLI.
    // e.g. /usr/local/bin/node  →  /usr/local
    // This avoids installing into a different prefix (e.g. .hermes) when multiple
    // node managers are present on the host.
    const npmPrefix = path.dirname(path.dirname(process.execPath));
    if (opts.dryRun) {
        console.log(`\n[dry-run] Would run: npm install -g --prefix ${npmPrefix} ${PKG}@latest`);
        console.log(`[dry-run] No changes made.`);
        return;
    }
    console.log(`\nInstalling ${PKG}@${latest} globally (prefix: ${npmPrefix})…`);
    const result = (0, child_process_1.spawnSync)('npm', ['install', '-g', '--prefix', npmPrefix, `${PKG}@latest`], { stdio: 'inherit' });
    if (result.status !== 0) {
        console.error(`✗ npm install failed (exit ${result.status}). Try with sudo if this is a permissions issue.`);
        process.exit(result.status ?? 1);
    }
    console.log(`\n✓ Updated to ${latest}.`);
    console.log(`  This refreshed the CLI, bundled UI (ui-dist), and the @doquflow/core + @doquflow/studio dependencies.`);
    const stale = await isPortInUse(DEFAULT_PORT);
    if (stale) {
        console.log('');
        console.log(`⚠  A DocuFlow server is still running on port ${DEFAULT_PORT} — it is the OLD version.`);
        console.log(`   Stop and restart it to use the new code:`);
        console.log(`     lsof -ti:${DEFAULT_PORT} | xargs kill`);
        console.log(`     docuflow ui`);
    }
}
