#!/usr/bin/env node
/**
 * Build script to run natively inside WSL
 * Handles both x64 and ARM64 builds
 * Reads configuration from build-config.json
 *
 * Usage from WSL:
 *   node builder/build-under-wsl.ts
 */

import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

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

interface BuildConfig {
    platforms: {
        windows?: boolean;
        wsl?: boolean;
        pi?: boolean;
        arm64?: boolean;
    };
    options?: {
        release?: boolean;
        verbose?: boolean;
        piHost?: string;
        piProjectPath?: string;
    };
}

function timestamp(): string {
    const now = new Date();
    return now.toTimeString().split(' ')[0];
}

interface BuildTarget {
    name: string;
    rustTarget: string;
    outputName: string;
    description: string;
}

const targets: Record<string, BuildTarget> = {
    x64: {
        name: 'x64',
        rustTarget: 'x86_64-unknown-linux-gnu',
        outputName: 'msgernative',
        description: 'Linux x64'
    },
    arm64: {
        name: 'arm64',
        rustTarget: 'aarch64-unknown-linux-gnu',
        outputName: 'msgernative-linux-aarch64',
        description: 'Linux ARM64'
    }
};

function checkToolchain(target: BuildTarget): boolean {
    try {
        const installed = execSync('rustup target list --installed', { encoding: 'utf-8' });
        return installed.includes(target.rustTarget);
    } catch {
        return false;
    }
}

function installToolchain(target: BuildTarget): boolean {
    console.log(`  [${timestamp()}] 📦 Installing ${target.description} toolchain...`);

    try {
        // Add Rust target
        execSync(`rustup target add ${target.rustTarget}`, { stdio: 'inherit' });

        // For ARM64, also install cross-compiler
        if (target.name === 'arm64') {
            console.log(`  [${timestamp()}] 📦 Installing ARM64 cross-compiler...`);
            execSync('sudo apt update && sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross', {
                stdio: 'inherit'
            });
        }

        console.log(`  [${timestamp()}] ✅ Toolchain installed`);
        return true;
    } catch (error: any) {
        console.error(`  [${timestamp()}] ❌ Failed to install toolchain: ${error.message}`);
        return false;
    }
}

function build(target: BuildTarget, verbose: boolean): boolean {
    console.log(`\n[${timestamp()}] 📦 Building ${target.description} binary...`);

    // Check toolchain
    if (!checkToolchain(target)) {
        console.log(`  [${timestamp()}] ⚙️  ${target.description} toolchain not found`);
        if (!installToolchain(target)) {
            return false;
        }
    }

    const nativeDir = path.join(__dirname, '..');
    const binDir = path.join(nativeDir, 'bin');
    const binaryPath = path.join(binDir, target.outputName);

    try {
        console.log(`  [${timestamp()}] 🔨 Compiling with cargo...`);
        execSync(`cargo build --release --target ${target.rustTarget}`, {
            cwd: nativeDir,
            stdio: verbose ? 'inherit' : 'pipe'
        });

        // Copy to bin directory
        if (!fs.existsSync(binDir)) {
            fs.mkdirSync(binDir, { recursive: true });
        }

        const sourcePath = path.join(nativeDir, 'target', target.rustTarget, 'release', 'msgernative');
        fs.copyFileSync(sourcePath, binaryPath);
        fs.chmodSync(binaryPath, 0o755);

        const stats = fs.statSync(binaryPath);
        const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
        console.log(`  [${timestamp()}] ✅ ${target.description} binary completed`);
        console.log(`  [${timestamp()}] 📊 Binary size: ${sizeMB} MB`);
        console.log(`  [${timestamp()}] 📁 Output: ${binaryPath}`);
        return true;
    } catch (error: any) {
        console.error(`  [${timestamp()}] ❌ Build failed: ${error.message}`);
        return false;
    }
}

function loadConfig(): BuildConfig {
    const configPath = path.join(__dirname, 'build-config.json');

    if (!fs.existsSync(configPath)) {
        console.error('❌ build-config.json not found');
        process.exit(1);
    }

    try {
        const content = fs.readFileSync(configPath, 'utf-8');
        return JSON.parse(content);
    } catch (error: any) {
        console.error(`❌ Failed to parse build-config.json: ${error.message}`);
        process.exit(1);
    }
}

function main() {
    console.log('🚀 WSL Native Builder\n');

    const config = loadConfig();
    const verboseFlag = config.options?.verbose ?? false;

    // Determine which targets to build based on config
    const requestedTargets: string[] = [];
    if (config.platforms.wsl) requestedTargets.push('x64');
    if (config.platforms.arm64) requestedTargets.push('arm64');

    if (requestedTargets.length === 0) {
        console.log('⚠️  No WSL platforms enabled in build-config.json');
        console.log('   Enable "wsl" for x64 or "arm64" for ARM64 builds');
        process.exit(0);
    }

    console.log(`📋 Configuration:`);
    console.log(`   Mode: ${config.options?.release ? 'release' : 'debug'}`);
    console.log(`   Targets: ${requestedTargets.join(', ')}`);
    console.log(`   Verbose: ${verboseFlag}\n`);

    const results: { target: string; success: boolean }[] = [];

    for (const targetName of requestedTargets) {
        const target = targets[targetName];
        if (!target) {
            console.error(`❌ Unknown target: ${targetName}`);
            console.error(`   Available targets: x64, arm64, all`);
            process.exit(1);
        }

        const success = build(target, verboseFlag);
        results.push({ target: targetName, success });
    }

    // Summary
    console.log('\n' + '='.repeat(50));
    console.log('📊 Build Summary:');
    console.log('='.repeat(50));

    for (const result of results) {
        const status = result.success ? '✅' : '❌';
        console.log(`${status} ${result.target}`);
    }

    const successCount = results.filter(r => r.success).length;
    const totalCount = results.length;

    console.log('='.repeat(50));
    console.log(`\n🎉 Completed: ${successCount}/${totalCount} builds successful\n`);

    if (successCount < totalCount) {
        process.exit(1);
    }
}

main();
