#!/usr/bin/env node

/**
 * @file check-electron-prerequisites.js
 * @description Verifies and installs required dependencies for Electron builds
 * 
 * This script checks if Python's distutils module is available, which is required
 * by node-gyp when compiling native Node.js modules during Electron packaging.
 * Without distutils, builds will fail with "ModuleNotFoundError: No module named 'distutils'".
 * 
 * The script performs the following actions:
 * 1. Checks if Python's distutils module is available
 * 2. If missing, offers to install setuptools package which provides distutils
 * 3. Attempts installation through pip or pip3
 * 4. Provides manual installation instructions if automated installation fails
 * 
 * Usage:
 *   - Direct execution: node scripts/check-electron-prerequisites.js
 *   - As npm script: npm run check:electron
 *   - Before builds: npm run check:electron && electron-builder
 * 
 * Exit codes:
 *   - 0: All prerequisites are met or were successfully installed
 *   - 1: Prerequisites are missing and weren't installed
 * 
 * @author [YOUR_NAME]
 * @version 1.0.0
 * @license MIT
 */

const { execSync } = require('child_process');
const readline = require('readline');
const chalk = require('chalk'); // You might need to add this to your dependencies

console.log(chalk.blue('🔍 Checking Electron build prerequisites...'));

/**
 * Checks if Python's distutils module is available
 * 
 * This function attempts to import the distutils module in Python.
 * If successful, it means node-gyp will be able to compile native modules.
 * If unsuccessful, the Electron build will likely fail when compiling native dependencies.
 * 
 * @returns {boolean} True if distutils is available, false otherwise
 * 
 * @example
 * if (checkDistutils()) {
 *   console.log('Ready to build Electron app');
 * }
 */
function checkDistutils() {
  try {
    // Attempt to import distutils using Python
    // We use stdio: 'ignore' to suppress any Python output
    execSync('python -c "import distutils"', { stdio: 'ignore' });
    console.log(chalk.green('✅ Python distutils is available'));
    return true;
  } catch (e) {
    // This error occurs if either Python is not found or if distutils is missing
    console.log(chalk.red('❌ Python distutils is missing'));
    return false;
  }
}

/**
 * Installs the setuptools package which provides distutils
 * 
 * This function attempts to install setuptools using pip or pip3.
 * Setuptools is a package that provides the distutils module needed by node-gyp.
 * In Python 3.12+, distutils was moved out of the standard library into setuptools.
 * 
 * The function tries multiple installation methods:
 * 1. First attempts with pip
 * 2. If that fails, tries with pip3
 * 3. If both fail, provides instructions for manual installation
 * 
 * @returns {Promise<boolean>} True if installation succeeded, false otherwise
 * 
 * @example
 * const success = await installSetuptools();
 * if (success) {
 *   console.log('Ready to proceed with build');
 * } else {
 *   console.log('Please fix prerequisites manually');
 * }
 */
async function installSetuptools() {
  console.log(chalk.yellow('📦 Attempting to install setuptools...'));
  
  try {
    // First try with pip, commonly used on all platforms
    execSync('pip install setuptools', { stdio: 'inherit' });
    console.log(chalk.green('✅ Successfully installed setuptools'));
    return true;
  } catch (pipError) {
    try {
      // If pip fails, try with pip3 (common on Linux distributions)
      console.log(chalk.yellow('⚠️ Trying with pip3...'));
      execSync('pip3 install setuptools', { stdio: 'inherit' });
      console.log(chalk.green('✅ Successfully installed setuptools using pip3'));
      return true;
    } catch (pip3Error) {
      // If both methods fail, provide manual installation guidance
      console.log(chalk.red('❌ Failed to install setuptools automatically'));
      console.log(chalk.yellow('📝 Please install it manually with:'));
      console.log('   pip install setuptools');
      console.log('   or');
      console.log('   sudo apt install python3-setuptools (on Debian/Ubuntu)');
      console.log('   sudo pacman -S python-setuptools (on Arch Linux)');
      console.log('   sudo dnf install python3-setuptools (on Fedora)');
      console.log('   brew install python-setuptools (on macOS with Homebrew)');
      return false;
    }
  }
}

/**
 * Main execution function
 * 
 * This function orchestrates the checking and installation process:
 * 1. Checks if distutils is already available
 * 2. If not, informs the user and prompts for installation
 * 3. Based on user input, attempts to install or exits
 * 
 * The function handles interactive user prompts and orchestrates
 * the overall flow of the script.
 * 
 * @returns {Promise<void>}
 * @throws Will exit process with code 1 if prerequisites aren't met
 */
async function main() {
  // First check if distutils is already available
  if (checkDistutils()) {
    // All prerequisites are met, exit successfully
    process.exit(0);
  }
  
  // Inform the user about the missing prerequisite
  console.log(chalk.yellow('⚠️ Python distutils is required for Electron builds'));
  console.log(chalk.yellow('⚠️ This is needed to compile native modules during the build process'));
  
  // Set up readline interface for user interaction
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  // Prompt the user for installation permission
  const answer = await new Promise(resolve => {
    rl.question(chalk.blue('Would you like to install setuptools now? (y/n) '), resolve);
  });
  
  // Clean up readline interface
  rl.close();
  
  if (answer.toLowerCase() === 'y') {
    // User agreed to installation
    const success = await installSetuptools();
    if (success) {
      // Installation succeeded, exit successfully
      process.exit(0);
    } else {
      // Installation failed, exit with error
      process.exit(1);
    }
  } else {
    // User declined installation
    console.log(chalk.yellow('⚠️ Build may fail without distutils'));
    process.exit(1);
  }
}

// Execute the main function and handle any uncaught errors
main().catch(error => {
  console.error(chalk.red('Error during prerequisites check:'), error);
  process.exit(1);
});