#!/usr/bin/env node
// scripts/install.js — postinstall hook для valency-viktor.
//
// Что делает:
//  1. Копирует прекомпилированный TUI-бинарь под текущую платформу из
//     bin/release/ → bin/viktor-tui[.exe], чтобы launch.js его нашёл.
//  2. Проверяет наличие Python (>=3.10). Если нет — печатает инструкцию
//     и завершается с кодом 0 (не валит установку).
//  3. Создаёт .venv и ставит requirements.txt для прокси.
//
// By Valency Labs.

'use strict';

const fs = require('fs');
const os = require('os');
const path = require('path');
const { spawnSync } = require('child_process');

const ROOT = path.resolve(__dirname, '..');
const PKG = require(path.join(ROOT, 'package.json'));
const BIN_DIR = path.join(ROOT, 'bin');
const RELEASE_DIR = path.join(ROOT, 'bin', 'release');
// Python-сорцы прокси лежат в корне пакета — viktor_valency/ + requirements.txt
const PY_DIR = ROOT;

const VERSION = PKG.version;

function log(...args) {
  console.log('[viktor-valency]', ...args);
}
function warn(...args) {
  console.warn('[viktor-valency]', ...args);
}

// platformAsset — какой бинарь из bin/release/ подходит этой платформе.
function platformAsset() {
  const platform = os.platform();
  const arch = os.arch();
  let suffix;
  if (platform === 'win32' && arch === 'x64') suffix = 'windows-amd64.exe';
  else if (platform === 'darwin' && arch === 'arm64') suffix = 'darwin-arm64';
  else if (platform === 'darwin' && arch === 'x64') suffix = 'darwin-amd64';
  else if (platform === 'linux' && arch === 'x64') suffix = 'linux-amd64';
  else if (platform === 'linux' && arch === 'arm64') suffix = 'linux-arm64';
  else throw new Error(`unsupported platform: ${platform}/${arch}`);
  const isWindows = platform === 'win32';
  const exe = isWindows ? 'viktor-tui.exe' : 'viktor-tui';
  const assetName = `viktor-tui-${suffix}`;
  return { exe, assetName, isWindows };
}

function placeTUIBinary() {
  const { exe, assetName, isWindows } = platformAsset();
  fs.mkdirSync(BIN_DIR, { recursive: true });
  const target = path.join(BIN_DIR, exe);

  // если уже есть (повторный install) — оставляем
  if (fs.existsSync(target)) {
    log(`TUI binary already present at ${target}`);
    return target;
  }

  const src = path.join(RELEASE_DIR, assetName);
  if (!fs.existsSync(src)) {
    warn(`не нашёл ${src} в пакете. Может, эта платформа не поддерживается`);
    warn('или бинарь был исключён через .npmignore. Собери вручную:');
    warn(`  cd tui && go build -o ../bin/${exe} ./cmd/viktor-tui/`);
    return null;
  }

  log(`copying TUI binary: ${assetName} → ${exe}`);
  fs.copyFileSync(src, target);
  if (!isWindows) fs.chmodSync(target, 0o755);
  log(`TUI ready: ${target}`);
  return target;
}

function detectPython() {
  const candidates = process.platform === 'win32'
    ? ['py -3', 'python', 'python3']
    : ['python3', 'python'];
  for (const c of candidates) {
    try {
      const [bin, ...args] = c.split(' ');
      const r = spawnSync(bin, [...args, '--version'], { encoding: 'utf-8' });
      if (r.status === 0 && /Python 3\.\d+/.test(r.stdout + r.stderr)) {
        return c;
      }
    } catch (_) { /* skip */ }
  }
  return null;
}

function ensurePython() {
  const py = detectPython();
  if (!py) {
    warn('Python 3.10+ не найден. Поставь Python и затем запусти:');
    warn('  npx valencyviktor    # повторно подтянет venv');
    warn('Windows: https://www.python.org/downloads/');
    warn('macOS:   brew install python@3.12');
    warn('Linux:   sudo apt install python3 python3-venv');
    return null;
  }
  log(`Python ok: ${py}`);
  return py;
}

function ensureVenv(pyCmd) {
  const venv = path.join(PY_DIR, '.venv');
  const venvPy = process.platform === 'win32'
    ? path.join(venv, 'Scripts', 'python.exe')
    : path.join(venv, 'bin', 'python');

  if (fs.existsSync(venvPy)) {
    log(`venv already exists at ${venv}`);
  } else {
    log(`creating venv: ${venv}`);
    const [bin, ...args] = pyCmd.split(' ');
    const r = spawnSync(bin, [...args, '-m', 'venv', venv], {
      cwd: PY_DIR,
      stdio: 'inherit',
    });
    if (r.status !== 0) {
      warn('не смог создать venv. Проверь, что есть python3-venv (Linux) или Python с venv-модулем.');
      return null;
    }
  }

  // ставим зависимости
  const req = path.join(PY_DIR, 'requirements.txt');
  if (!fs.existsSync(req)) {
    warn(`requirements.txt не найден в ${PY_DIR} — пропускаю pip install`);
    return venvPy;
  }
  log(`installing requirements: ${req}`);
  const r = spawnSync(venvPy, ['-m', 'pip', 'install', '-q', '--upgrade', 'pip'], { stdio: 'inherit' });
  if (r.status !== 0) warn('pip upgrade failed (продолжаю)');
  const r2 = spawnSync(venvPy, ['-m', 'pip', 'install', '-q', '-r', req], { stdio: 'inherit' });
  if (r2.status !== 0) {
    warn('pip install -r requirements.txt failed');
    return null;
  }
  log('Python dependencies installed.');
  return venvPy;
}

(async () => {
  try {
    log(`installing v${VERSION}...`);
    log(`platform: ${os.platform()} ${os.arch()} · node ${process.version}`);

    placeTUIBinary();

    const py = ensurePython();
    if (py) {
      ensureVenv(py);
    }

    log('done. Запусти TUI: valencyviktor');
  } catch (e) {
    // Не валим npm install — даём пользователю инструкцию и выходим с 0.
    warn('postinstall ошибка:', e.message);
    warn('Запусти `npx valencyviktor` после ручной починки окружения.');
    process.exit(0);
  }
})();
