/**
 * Opt-out, bounded, offline-safe, telemetry-free "newer version available"
 * check. It does a single GET to the npm registry for the package's latest
 * version and compares semver. It sends NO user data, never blocks startup, and
 * silently yields nothing on any error/timeout. It NEVER installs anything —
 * the actual update is the separate `patchtrail update` command.
 */
const REGISTRY_BASE = "https://registry.npmjs.org";
const PACKAGE_NAME = "@patchtrail/patchtrail";
/**
 * Returns whether a newer published version exists. Disabled (returns
 * unavailable) when `--no-update-check` / PATCHTRAIL_NO_UPDATE_CHECK is set.
 */
export async function checkForUpdate(options) {
    if (options.disabled)
        return { available: false };
    const fetchImpl = options.fetchImpl ?? globalThis.fetch;
    if (!fetchImpl)
        return { available: false };
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 1_500);
    if (typeof timer === "object" && "unref" in timer)
        timer.unref();
    try {
        const response = await fetchImpl(`${REGISTRY_BASE}/${PACKAGE_NAME}/latest`, { signal: controller.signal, headers: { accept: "application/json" } });
        if (!response.ok)
            return { available: false };
        const body = (await response.json());
        const latest = typeof body.version === "string" ? body.version : undefined;
        if (!latest)
            return { available: false };
        return isNewer(latest, options.currentVersion)
            ? { available: true, current: options.currentVersion, latest }
            : { available: false };
    }
    catch {
        // Offline / slow / aborted / malformed → silently skip.
        return { available: false };
    }
    finally {
        clearTimeout(timer);
    }
}
/** Minimal, dependency-free semver "a > b" comparison (numeric core only;
 * prereleases are treated conservatively so we never nag downward). */
export function isNewer(a, b) {
    const pa = parseSemverCore(a);
    const pb = parseSemverCore(b);
    if (!pa || !pb)
        return false;
    for (let i = 0; i < 3; i += 1) {
        const left = pa[i] ?? 0;
        const right = pb[i] ?? 0;
        if (left > right)
            return true;
        if (left < right)
            return false;
    }
    return false;
}
function parseSemverCore(value) {
    const core = value.split("+")[0]?.split("-")[0] ?? "";
    const parts = core.split(".");
    if (parts.length !== 3)
        return undefined;
    const result = [0, 0, 0];
    for (let i = 0; i < 3; i += 1) {
        const n = Number.parseInt(parts[i] ?? "", 10);
        if (!Number.isInteger(n) || n < 0)
            return undefined;
        result[i] = n;
    }
    return result;
}
