#!/usr/bin/env node
/**
 * One-time setup script for 4runr-os
 * Auto-detects and fixes all dependencies
 */

import { execSync, spawn } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import * as readline from 'readline';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const platform = process.platform;
const isWindows = platform === 'win32';

// Main setup function (async for delays)
async function runSetup() {
console.log('🔍 Checking 4runr-os setup...\n');

// Check Node.js
try {
  const nodeVersion = execSync('node --version', { encoding: 'utf-8' }).trim();
  const majorVersion = parseInt(nodeVersion.replace('v', '').split('.')[0]);
  if (majorVersion < 18) {
    console.error('❌ Node.js 18+ required. Current:', nodeVersion);
    console.error('   Install from: https://nodejs.org/');
    process.exit(1);
  }
  console.log('✅ Node.js:', nodeVersion);
} catch {
  console.error('❌ Node.js not found. Install from: https://nodejs.org/');
  process.exit(1);
}

// Check npm
try {
  const npmVersion = execSync('npm --version', { encoding: 'utf-8' }).trim();
  console.log('✅ npm:', npmVersion);
} catch {
  console.error('❌ npm not found. Install Node.js from: https://nodejs.org/');
  process.exit(1);
}

// Check Rust
let rustInstalled = false;
let rustNeedsGNU = false;
try {
  execSync('cargo --version', { stdio: 'ignore' });
  rustInstalled = true;
  console.log('✅ Rust is installed');
  
  // Check if MSVC linker is available (Windows only)
  if (isWindows) {
    try {
      execSync('where link.exe', { stdio: 'ignore' });
      console.log('✅ MSVC linker found');
    } catch {
      console.log('⚠️  MSVC linker not found - will use GNU toolchain');
      rustNeedsGNU = true;
    }
  }
} catch {
  console.log('⚠️  Rust not installed');
  console.log('\n   Rust is required to build mk3-tui.');
  console.log('   Install Rust: https://rustup.rs/');
  console.log('   Or run: curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh\n');
  console.log('   After installing Rust, run 4runr-setup again.\n');
  process.exit(1);
  
  // Note: We don't auto-install Rust anymore to avoid modifying user's system without explicit consent
  // Users should install Rust themselves using the official installer
}

// Fix Rust toolchain on Windows (use GNU if MSVC not available)
if (isWindows && rustInstalled && rustNeedsGNU) {
  console.log('\n🔧 Configuring Rust for Windows (GNU toolchain)...');
  
  // Check if MinGW is installed (required for GNU toolchain)
  let mingwInstalled = false;
  let mingwPath = '';
  
  // PRIORITY 1: Check if MSYS2 exists FIRST (most reliable)
  const msys2MingwPath = 'C:\\msys64\\mingw64\\bin';
  const msys2Bash = 'C:\\msys64\\usr\\bin\\bash.exe';
  
  if (fs.existsSync(msys2Bash)) {
    console.log('   ✅ MSYS2 found - checking for MinGW...');
    if (fs.existsSync(path.join(msys2MingwPath, 'dlltool.exe'))) {
      mingwInstalled = true;
      mingwPath = msys2MingwPath;
      console.log('   ✅ MinGW found in MSYS2');
    } else {
      // MSYS2 exists but MinGW not installed - install it automatically
      console.log('   🔨 Installing MinGW toolchain in MSYS2 (this may take 2-3 minutes)...');
      try {
        execSync(`"${msys2Bash}" -lc "pacman -S mingw-w64-x86_64-toolchain --noconfirm"`, {
          stdio: 'inherit',
          timeout: 300000 // 5 minutes
        });
        
        if (fs.existsSync(path.join(msys2MingwPath, 'dlltool.exe'))) {
          mingwInstalled = true;
          mingwPath = msys2MingwPath;
          console.log('   ✅ MinGW toolchain installed successfully');
        } else {
          console.warn('   ⚠️  Installation completed but MinGW not found');
          console.warn('   Please restart terminal and run 4runr-setup again');
          process.exit(0);
        }
      } catch (installError) {
        console.error('   ❌ Failed to install MinGW automatically');
        console.error('   Quick fix - run this command:');
        console.error(`   "${msys2Bash}" -lc "pacman -S mingw-w64-x86_64-toolchain --noconfirm"`);
        console.error('   Then restart terminal and run: 4runr-setup\n');
        process.exit(1);
      }
    }
    
    // Add to PATH for current session
    if (mingwInstalled && mingwPath) {
      console.log(`   ✅ Adding ${mingwPath} to PATH for this session...`);
      process.env.PATH = process.env.PATH ? `${mingwPath};${process.env.PATH}` : mingwPath;
    }
  }
  
  // PRIORITY 2: Check PATH if MSYS2 didn't work
  if (!mingwInstalled) {
    try {
      const dlltoolPath = execSync('where dlltool.exe', { encoding: 'utf-8', stdio: 'pipe' }).trim();
      mingwInstalled = true;
      mingwPath = path.dirname(dlltoolPath);
      console.log('   ✅ MinGW found in PATH at:', mingwPath);
    } catch {
      // Check other common paths
      console.log('   Checking common installation locations...');
      const commonPaths = [
        'C:\\mingw64\\bin',
        'C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin',
      ];
      
      for (const testPath of commonPaths) {
        if (fs.existsSync(testPath)) {
          const dlltoolPath = path.join(testPath, 'dlltool.exe');
          if (fs.existsSync(dlltoolPath)) {
            mingwInstalled = true;
            mingwPath = testPath;
            console.log('   ✅ MinGW found at:', mingwPath);
            process.env.PATH = process.env.PATH ? `${mingwPath};${process.env.PATH}` : mingwPath;
            break;
          }
        }
      }
    }
  }
    
  // PRIORITY 3: Only if still not found, try winget installation
  if (!mingwInstalled) {
    console.log('   Installing MinGW-w64 via winget...');
    
    // Try multiple installation methods
    let installed = false;
    
    // Try winget - MSYS2 is more reliable and includes MinGW
    const wingetPackages = [
      'msys2.msys2',           // MSYS2 (includes MinGW, most reliable)
      'mingw-w64.mingw-w64',   // Direct MinGW package
      'mingw-w64',             // Alternative MinGW package name
    ];
    
    for (const pkg of wingetPackages) {
      try {
        console.log(`   Trying: winget install ${pkg}...`);
        execSync(`winget install ${pkg} --accept-package-agreements --accept-source-agreements --silent`, { 
          stdio: 'pipe',
          timeout: 120000 // 2 minutes for MSYS2
        });
        installed = true;
        console.log(`   ✅ Installed via winget: ${pkg}`);
        
        // If MSYS2 was just installed via winget, install MinGW inside it
        if (pkg === 'msys2.msys2') {
          // Wait a moment for MSYS2 installation to complete
          console.log('   Waiting for MSYS2 installation to complete...');
          const { setTimeout } = await import('timers/promises');
          await setTimeout(5000);
          
          // Check if MinGW is already installed
          if (fs.existsSync(path.join(msys2MingwPath, 'dlltool.exe'))) {
            console.log(`   ✅ MinGW already installed in MSYS2`);
            mingwInstalled = true;
            mingwPath = msys2MingwPath;
          } else {
            // Automatically install MinGW toolchain via MSYS2
            console.log('   🔨 Installing MinGW toolchain in MSYS2 (this may take 2-3 minutes)...');
            try {
              execSync(`"${msys2Bash}" -lc "pacman -S mingw-w64-x86_64-toolchain --noconfirm"`, {
                stdio: 'inherit',
                timeout: 300000 // 5 minutes for installation
              });
              
              // Verify installation
              if (fs.existsSync(path.join(msys2MingwPath, 'dlltool.exe'))) {
                console.log('   ✅ MinGW toolchain installed successfully');
                mingwInstalled = true;
                mingwPath = msys2MingwPath;
              } else {
                console.warn('   ⚠️  Installation completed but MinGW not found. Please restart terminal and run 4runr-setup again.');
                process.exit(0);
              }
            } catch (installError) {
              console.error('   ❌ Failed to install MinGW automatically');
              console.error('   Quick fix - run this command:');
              console.error(`   "${msys2Bash}" -lc "pacman -S mingw-w64-x86_64-toolchain --noconfirm"`);
              console.error('   Then restart terminal and run: 4runr-setup\n');
              process.exit(1);
            }
          }
          
          // Add to PATH for current session
          if (mingwInstalled && mingwPath) {
            console.log(`   ✅ Adding ${mingwPath} to PATH for this session...`);
            process.env.PATH = process.env.PATH ? `${mingwPath};${process.env.PATH}` : mingwPath;
          }
        } else {
          // Direct MinGW package - wait and check PATH
          const { setTimeout } = await import('timers/promises');
          await setTimeout(2000);
          try {
            const dlltoolPath = execSync('where dlltool.exe', { encoding: 'utf-8', stdio: 'pipe' }).trim();
            mingwInstalled = true;
            mingwPath = path.dirname(dlltoolPath);
          } catch {
            // Not in PATH yet - user will need to restart terminal
            console.warn('   ⚠️  Installed but not in PATH - please restart terminal');
          }
        }
        break;
      } catch (err) {
        // Try next package
        continue;
      }
    }
    
    if (!installed) {
      console.error('\n❌ Failed to install MinGW automatically via winget');
      console.error('\n   Please install MinGW-w64 manually using one of these methods:\n');
      console.error('   Option 1: MSYS2 via winget (Easiest)');
      console.error('   Run: winget install msys2.msys2');
      console.error('   Then:');
      console.error('   1. Open MSYS2 terminal (search for "MSYS2 MSYS" in Start menu)');
      console.error('   2. Run: pacman -S mingw-w64-x86_64-toolchain --noconfirm');
      console.error('   3. Add C:\\msys64\\mingw64\\bin to your PATH');
      console.error('   4. Restart terminal and run: 4runr-setup\n');
      console.error('   Option 1b: MSYS2 Manual Download');
      console.error('   1. Download: https://www.msys2.org/');
      console.error('   2. Install MSYS2');
      console.error('   3. Open MSYS2 terminal and run: pacman -S mingw-w64-x86_64-toolchain --noconfirm');
      console.error('   4. Add C:\\msys64\\mingw64\\bin to your PATH');
      console.error('   5. Restart terminal and run: 4runr-setup\n');
      console.error('   Option 2: WinLibs (Direct Download)');
      console.error('   1. Download: https://winlibs.com/');
      console.error('   2. Extract to C:\\mingw64');
      console.error('   3. Add C:\\mingw64\\bin to your PATH');
      console.error('   4. Restart terminal and run: 4runr-setup\n');
      console.error('   Option 3: Chocolatey (if installed)');
      console.error('   choco install mingw\n');
      process.exit(1);
    } else {
      console.log('\n✅ MinGW-w64 installed!');
      console.log('   IMPORTANT: Please restart your terminal to update PATH');
      console.log('   Then run: 4runr-setup\n');
      process.exit(0);
    }
  }
  
  // Configure Rust to use GNU toolchain if MinGW is installed
  if (mingwInstalled) {
    // Make sure MinGW is in PATH for cargo
    if (mingwPath && process.env.PATH && !process.env.PATH.includes(mingwPath)) {
      process.env.PATH = `${mingwPath};${process.env.PATH}`;
    } else if (mingwPath && !process.env.PATH) {
      process.env.PATH = mingwPath;
    }
    
    try {
      execSync('rustup toolchain install stable-x86_64-pc-windows-gnu', { stdio: 'pipe' });
      execSync('rustup default stable-x86_64-pc-windows-gnu', { stdio: 'pipe' });
      console.log('✅ GNU toolchain installed and set as default');
    } catch (error) {
      console.warn('⚠️  Failed to install GNU toolchain automatically');
      console.warn('   You can install manually:');
      console.warn('   rustup toolchain install stable-x86_64-pc-windows-gnu');
      console.warn('   rustup default stable-x86_64-pc-windows-gnu');
    }
  }
}

// Continue with rest of setup (outside Windows-specific block)
console.log('\n📦 Checking 4runr-os installation...');
try {
  // Check if 4r command exists by checking npm global bin
  const npmPrefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim();
  const globalBinPath = isWindows 
    ? path.join(npmPrefix, '4r.cmd')
    : path.join(npmPrefix, 'bin', '4r');
  
  // Also check for 4runr-os package in node_modules
  const globalPackagePath = isWindows
    ? path.join(npmPrefix, 'node_modules', '4runr-os', 'package.json')
    : path.join(npmPrefix, 'lib', 'node_modules', '4runr-os', 'package.json');
  
  if (fs.existsSync(globalBinPath) || fs.existsSync(globalPackagePath)) {
    console.log('✅ 4runr-os is installed');
  } else {
    throw new Error('4r not found');
  }
} catch {
  console.log('⚠️  4runr-os not found');
  console.log('   Installing 4runr-os...');
  try {
    execSync('npm install -g 4runr-os@latest', { stdio: 'inherit' });
    console.log('✅ 4runr-os installed');
  } catch {
    console.error('❌ Failed to install 4runr-os');
    console.error('   Run manually: npm install -g 4runr-os@latest');
    process.exit(1);
  }
}

  // Verify mk3-tui binary (check global install location)
  let mk3Dir = null;
  try {
    // Try to find global install location
    const npmPrefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim();
    const globalPath = isWindows 
      ? path.join(npmPrefix, 'node_modules', '4runr-os', 'mk3-tui')
      : path.join(npmPrefix, 'lib', 'node_modules', '4runr-os', 'mk3-tui');
    
    if (fs.existsSync(globalPath)) {
      mk3Dir = globalPath;
    }
  } catch {
    // Fallback to local
    mk3Dir = path.join(__dirname, '..', 'mk3-tui');
  }

  if (mk3Dir && fs.existsSync(mk3Dir)) {
    const binaryName = isWindows ? 'mk3-tui.exe' : 'mk3-tui';
    const binaryPath = path.join(mk3Dir, 'target', 'release', binaryName);
    
    if (!fs.existsSync(binaryPath)) {
      console.log('\n🔨 Building mk3-tui binary...');
      try {
        execSync('cargo build --release', {
          cwd: mk3Dir,
          stdio: 'inherit',
        });
        console.log('✅ mk3-tui built successfully');
        
        // Clean up build artifacts to save disk space (keep only release binary)
        cleanupBuildArtifacts();
      } catch (error) {
        console.warn('⚠️  Failed to build mk3-tui');
        console.warn('   The binary will be built automatically on first run of 4r');
      }
    } else {
      console.log('✅ mk3-tui binary found');
    }
  } else {
    console.log('⚠️  mk3-tui source not found - will build on first run of 4r');
  }

  console.log('\n✅ Setup complete! You can now run: 4r\n');
}

// Run the setup
runSetup()
  .then(() => {
    // Setup completed successfully
    process.exit(0);
  })
  .catch((error) => {
    console.error('\n❌ Setup failed:', error);
    process.exit(1);
  });

