#!/usr/bin/env node
/**
 * Запускается из bin/cursorconnect.sh до dist/index.js.
 * Обновляет global npm, если версия ниже latest/min на relay (bootstrap для старых CLI).
 */
import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { spawnSync } from 'child_process';

const EXIT_OK = 0;
const EXIT_REEXEC = 10;
const EXIT_FAIL = 1;

const binDir = dirname(fileURLToPath(import.meta.url));
const root = join(binDir, '..');

function parseSemver(v) {
  const m = String(v).trim().match(/^(\d+)\.(\d+)\.(\d+)/);
  if (!m) return null;
  return [Number(m[1]), Number(m[2]), Number(m[3])];
}

function isAtLeast(current, minimum) {
  const a = parseSemver(current);
  const b = parseSemver(minimum);
  if (!a || !b) return true;
  for (let i = 0; i < 3; i++) {
    if (a[i] !== b[i]) return a[i] > b[i];
  }
  return true;
}

function defaultRelayUrl() {
  try {
    const raw = readFileSync(join(root, 'config.env.defaults'), 'utf8');
    const m = raw.match(/^RELAY_URL=(.+)$/m);
    if (m) return m[1].trim().replace(/\/$/, '');
  } catch {
    /* ignore */
  }
  return 'https://cc.fanpay.online';
}

function resolveNpm() {
  const r = spawnSync('bash', ['-lc', 'command -v npm'], { encoding: 'utf8' });
  return r.status === 0 && r.stdout.trim() ? r.stdout.trim() : 'npm';
}

async function main() {
  if (process.env.CURSORCONNECT_NO_AUTO_UPDATE === '1') {
    process.exit(EXIT_OK);
  }
  if (process.env.CURSORCONNECT_UPDATE_ATTEMPTED === '1') {
    process.exit(EXIT_OK);
  }

  const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
  const current = pkg.version?.trim() || '0.0.0';
  const relay =
    (process.env.CURSORCONNECT_RELAY_URL || process.env.RELAY_URL || defaultRelayUrl()).replace(
      /\/$/,
      ''
    );

  let policy;
  try {
    const res = await fetch(`${relay}/api/version-policy`, {
      signal: AbortSignal.timeout(12_000),
    });
    if (!res.ok) process.exit(EXIT_OK);
    policy = await res.json();
  } catch {
    process.exit(EXIT_OK);
  }

  const latest = policy.latestCliVersion || current;
  const min = policy.minCliVersion || '0.0.0';
  const needsLatest = !isAtLeast(current, latest);
  const needsMin = !isAtLeast(current, min);
  if (!needsLatest && !needsMin) process.exit(EXIT_OK);

  const target = needsLatest ? latest : min;
  console.log(
    `[cursorconnect] Обновление ${current} → ${target} (npm install -g cursorconnect@latest)…`
  );

  const npm = resolveNpm();
  const r = spawnSync(npm, ['install', '-g', 'cursorconnect@latest'], {
    stdio: 'inherit',
    env: process.env,
  });
  if (r.status !== 0) {
    console.error('[cursorconnect] Автообновление не удалось — обновите вручную.');
    process.exit(needsMin ? EXIT_FAIL : EXIT_OK);
  }
  process.exit(EXIT_REEXEC);
}

main().catch((e) => {
  console.error('[cursorconnect] pre-start-update:', e);
  process.exit(EXIT_OK);
});
