"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.inferNpmPackageNameFromSpec = inferNpmPackageNameFromSpec;
exports.resolveNpxPackageRoot = resolveNpxPackageRoot;
const child_process_1 = require("child_process");
const path_1 = __importDefault(require("path"));
function getNpxBin() {
    return process.platform === 'win32' ? 'npx.cmd' : 'npx';
}
async function runCapture(cmd, args) {
    return await new Promise((resolve) => {
        const p = (0, child_process_1.spawn)(cmd, [...args], { stdio: ['ignore', 'pipe', 'pipe'] });
        const stdoutChunks = [];
        const stderrChunks = [];
        p.stdout.on('data', (b) => stdoutChunks.push(b));
        p.stderr.on('data', (b) => stderrChunks.push(b));
        p.on('close', (code) => {
            const stdout = Buffer.concat(stdoutChunks).toString('utf-8');
            const stderr = Buffer.concat(stderrChunks).toString('utf-8');
            if (code === 0) {
                resolve({ kind: 'ok', stdout });
                return;
            }
            resolve({
                kind: 'error',
                errorText: `Command failed (exit=${code ?? 'unknown'}): ${cmd} ${args.join(' ')}`,
                stdout,
                stderr,
            });
        });
        p.on('error', (err) => {
            resolve({
                kind: 'error',
                errorText: `Failed to spawn '${cmd}': ${err instanceof Error ? err.message : String(err)}`,
                stdout: Buffer.concat(stdoutChunks).toString('utf-8'),
                stderr: Buffer.concat(stderrChunks).toString('utf-8'),
            });
        });
    });
}
function inferNpmPackageNameFromSpec(spec) {
    const s = spec.trim();
    if (s === '')
        return null;
    if (s.includes('://'))
        return null;
    if (s.startsWith('git+'))
        return null;
    if (s.includes(' '))
        return null;
    // Reject paths/URLs (for now).
    if (s.includes('/') && !s.startsWith('@'))
        return null;
    if (s.startsWith('@')) {
        // @scope/name or @scope/name@version
        const slash = s.indexOf('/');
        if (slash <= 1)
            return null;
        const at = s.lastIndexOf('@');
        if (at > 0 && at > slash) {
            return s.slice(0, at);
        }
        return s;
    }
    const at = s.lastIndexOf('@');
    if (at > 0) {
        return s.slice(0, at);
    }
    return s;
}
async function resolveNpxPackageRoot(params) {
    const packageName = inferNpmPackageNameFromSpec(params.spec);
    if (!packageName) {
        return {
            kind: 'error',
            errorText: `Unsupported npx spec: '${params.spec}'. ` +
                `For now only npm package specs are supported (e.g. 'name', 'name@1.2.3', '@scope/name@1.2.3'). ` +
                `Use 'dominds install --local <path>' for local development packages.`,
        };
    }
    const script = [
        "const path=require('path');",
        `const p=require.resolve(${JSON.stringify(`${packageName}/package.json`)});`,
        'console.log(path.dirname(p));',
    ].join('');
    const result = await runCapture(getNpxBin(), ['-y', '-p', params.spec, 'node', '-e', script]);
    if (result.kind === 'error') {
        const detail = [result.errorText, result.stderr.trim(), result.stdout.trim()]
            .filter((s) => s !== '')
            .join('\n');
        return { kind: 'error', errorText: detail };
    }
    const out = result.stdout.trim();
    if (out === '') {
        return { kind: 'error', errorText: `npx returned empty output for spec '${params.spec}'` };
    }
    const packageRootAbs = path_1.default.resolve(out);
    return { kind: 'ok', packageName, packageRootAbs };
}
