#!/usr/bin/env node
import { VLCodeLite } from '../src/app.js';
import fs from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const crashLogPath = resolveCrashLogPath();

const CRASH_LOG_MAX_BYTES = 10 * 1024 * 1024; // 10 MB

function resolveCrashLogPath() {
  const packagedLogPath = process.env.VLCODE_LOG_DIR
    ? path.join(process.env.VLCODE_LOG_DIR, 'backend-crash.log')
    : path.join(os.homedir(), '.vl-code', 'logs', 'backend-crash.log');
  if (process.env.VLCODE_IS_PACKAGED === '1' || __dirname.includes('app.asar')) {
    return packagedLogPath;
  }
  return path.join(__dirname, '..', '.vlcode-lite', 'crash.log');
}

function safeConsoleError(...args) {
  try {
    console.error(...args);
  } catch {}
}

function appendCrashLog(level, msg) {
  const entry = `[${new Date().toISOString()}] ${level}: ${msg}\n`;
  try {
    const dir = path.dirname(crashLogPath);
    if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
    if (fs.existsSync(crashLogPath)) {
      const stat = fs.statSync(crashLogPath);
      if (stat.size > CRASH_LOG_MAX_BYTES) {
        const buf = fs.readFileSync(crashLogPath, 'utf-8');
        const keepFrom = buf.length - Math.floor(CRASH_LOG_MAX_BYTES / 2);
        const nextNewline = buf.indexOf('\n', keepFrom);
        fs.writeFileSync(crashLogPath, '[LOG ROTATED]\n' + buf.slice(nextNewline + 1));
      }
    }
    fs.appendFileSync(crashLogPath, entry);
  } catch (_) {}
}

process.on('uncaughtException', (err) => {
  const stack = err.stack || String(err);
  safeConsoleError('[FATAL] Uncaught exception:', stack);
  appendCrashLog('UNCAUGHT', stack);
});

process.on('unhandledRejection', (reason) => {
  const name = reason?.name || reason?.constructor?.name || '';
  const msg = reason?.message || '';
  if (name === 'APIUserAbortError' || name === 'AbortError' ||
      msg === 'Request was aborted.' || msg.includes('aborted')) return;
  safeConsoleError('[Server] Unhandled rejection:', msg || reason);
  appendCrashLog('REJECTION', msg || String(reason));
});

const app = new VLCodeLite();
app.run(process.argv.slice(2)).catch(err => {
  safeConsoleError('Fatal error:', err.message);
  appendCrashLog('FATAL', err.stack || String(err));
  process.exit(1);
});
