/**
 * OTA Packaging Script
 * Generates www.bin from dist/ using mklittlefs or littlefs-python.
 */

import { execSync } from 'child_process';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const projectRoot = resolve(__dirname, '..');
const distDir = resolve(projectRoot, 'dist');
const binDir = resolve(projectRoot, 'bin');
const versionFile = resolve(projectRoot, 'version.json');

// Ensure bin directory exists
if (!existsSync(binDir)) {
    mkdirSync(binDir, { recursive: true });
}

// Configuration matching partitions.csv (1MB = 1048576 bytes)
const FS_SIZE = 1048576;
const BLOCK_SIZE = 4096;
const PAGE_SIZE = 256;

console.log('--- OTA Packaging ---');

/**
 * Handle versioning: Read current version
 */
function getVersion() {
    if (existsSync(versionFile)) {
        try {
            return JSON.parse(readFileSync(versionFile, 'utf8'));
        } catch (e) {
            console.warn('Warning: Could not read version.json:', e.message);
        }
    }
    return { major: 0, minor: 0, revision: 0 };
}

/**
 * Increment and save revision
 */
function incrementVersion(version) {
    try {
        version.revision = (version.revision || 0) + 1;
        writeFileSync(versionFile, JSON.stringify(version, null, 2));
        console.log(`Version incremented to: ${version.major}.${version.minor}.${version.revision} for next build.`);
    } catch (e) {
        console.warn('Warning: Could not update version.json:', e.message);
    }
}

/**
 * Simple .env parser to load MKLITTLEFS_PATH without external dependencies
 */
function loadEnv() {
    const envPaths = [
        resolve(projectRoot, '.env.local'),
        resolve(projectRoot, '.env')
    ];
    
    for (const path of envPaths) {
        if (existsSync(path)) {
            console.log(`Loading config from: ${path}`);
            const content = readFileSync(path, 'utf8');
            content.split('\n').forEach(line => {
                const [key, ...valueParts] = line.split('=');
                if (key && valueParts.length > 0) {
                    const value = valueParts.join('=').trim().replace(/^["']|["']$/g, '');
                    process.env[key.trim()] = value;
                }
            });
        }
    }
}

loadEnv();
const version = getVersion();
const versionStr = `${version.major}.${version.minor}.${version.revision}`;
const outputFile = resolve(binDir, `www_v${versionStr}.bin`);

if (!existsSync(distDir)) {
    console.error('Error: dist/ directory not found. Run "npm run build:esp32" first.');
    process.exit(1);
}

// Try to find mklittlefs or littlefs-python
const findTool = () => {
    // 1. Check environment variable (from manual set or .env)
    if (process.env.MKLITTLEFS_PATH) {
        if (existsSync(process.env.MKLITTLEFS_PATH)) {
            return process.env.MKLITTLEFS_PATH;
        }
        console.warn(`Warning: MKLITTLEFS_PATH set to ${process.env.MKLITTLEFS_PATH} but file not found.`);
    }

    // 2. Check system PATH
    const tools = ['mklittlefs', 'littlefs-python'];
    for (const tool of tools) {
        try {
            execSync(`${tool} --version`, { stdio: 'ignore' });
            return tool;
        } catch (e) {
            // Not in path
        }
    }

    return null;
};

const tool = findTool();

if (!tool) {
    console.error('Error: No LittleFS tool found (checked mklittlefs and littlefs-python).');
    console.info('Please set MKLITTLEFS_PATH in your .env file.');
    console.info('Example: MKLITTLEFS_PATH=C:\\Espressif\\tools\\mklittlefs\\v3.2.0\\mklittlefs.exe');
    process.exit(1);
}

try {
    console.log(`Using tool: ${tool}`);
    console.log(`Packaging ${distDir} -> ${outputFile}...`);

    let cmd;
    // Check if it is the Python version or the C++ version
    if (tool.includes('littlefs-python')) {
        // Python style: littlefs-python create <dir> <output> --fs-size=<size> --block-size=<block>
        cmd = `"${tool}" create "${distDir}" "${outputFile}" --fs-size=${FS_SIZE} --block-size=${BLOCK_SIZE}`;
    } else {
        // C++ style: mklittlefs -c <dir> -s <size> -b <block> -p <page> <output>
        cmd = `"${tool}" -c "${distDir}" -s ${FS_SIZE} -b ${BLOCK_SIZE} -p ${PAGE_SIZE} "${outputFile}"`;
    }

    console.log(`Running: ${cmd}`);
    execSync(cmd, { stdio: 'inherit' });
    console.log('Success: www.bin created.');
    
    // Auto-increment for the next build
    incrementVersion(version);
} catch (e) {
    console.error('Error during packaging:', e.message);
    process.exit(1);
}
