#!/usr/bin/env node

/**
 * 演示并行处理效果的脚本
 */

const path = require('path');
const fs = require('fs');

async function demoParallelProcessing() {
    console.log('🚀 Parallel Processing Demo');
    console.log('============================');
    console.log('');
    
    const rootDir = path.dirname(__dirname); // 回到项目根目录
    const distDir = path.join(rootDir, 'dist');
    
    console.log('📁 Checking dist directory...');
    
    if (!fs.existsSync(distDir)) {
        console.log('❌ Dist directory not found');
        console.log('💡 Building demo files instead...');
        
        // 创建演示文件
        await createDemoFiles();
        return await demoWithCreatedFiles();
    }
    
    console.log(`✅ Found dist directory: ${distDir}`);
    
    // 统计dist目录中的JS文件
    const jsFiles = await countJsFiles(distDir);
    console.log(`📝 Found ${jsFiles} JavaScript files`);
    
    if (jsFiles > 3) {
        console.log('🎯 Perfect for parallel processing!');
        console.log('');
        console.log('💡 Commands to try:');
        console.log('   node scripts/optimize-dist.js              # Automatic parallel processing');
        console.log('   node scripts/optimized-processor.js ./dist # Manual parallel processing');
        console.log('   node scripts/performance-test.js          # Performance comparison');
        console.log('');
        console.log('⚡ Parallel processing features:');
        console.log('   • ✅ Worker threads for concurrent file processing');
        console.log('   • ✅ Up to 4 parallel workers');
        console.log('   • ✅ Intelligent caching to avoid reprocessing');
        console.log('   • ✅ Fallback to single-thread when needed');
    } else {
        console.log('📝 Fewer than 4 files, single-thread may be more efficient');
    }
}

async function createDemoFiles() {
    const demoDir = path.join(__dirname, 'demo-files');
    
    // 清理旧的演示文件
    if (fs.existsSync(demoDir)) {
        fs.rmSync(demoDir, { recursive: true, force: true });
    }
    
    fs.mkdirSync(demoDir, { recursive: true });
    
    console.log('📝 Creating demo files for parallel processing test...');
    
    // 创建多个不同大小的JS文件
    const demoFiles = [
        {
            name: 'utils.js',
            content: `
// Utility functions
function formatNumber(num) {
    console.log("Formatting number:", num);
    return num.toLocaleString();
}

function formatDate(date) {
    console.info("Formatting date:", date);
    return date.toISOString().split('T')[0];
}

function validateEmail(email) {
    console.debug("Validating email:", email);
    const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
    const result = regex.test(email);
    console.log("Email validation result:", result);
    return result;
}

console.warn("Utils module loaded");
`
        },
        {
            name: 'api-client.js',
            content: `
// API client
class ApiClient {
    constructor(baseUrl) {
        console.log("Creating API client for:", baseUrl);
        this.baseUrl = baseUrl;
        this.cache = new Map();
    }
    
    async request(endpoint, options = {}) {
        console.info("Making request to:", endpoint);
        console.debug("Request options:", options);
        
        const url = this.baseUrl + endpoint;
        console.log("Full URL:", url);
        
        try {
            const response = await fetch(url, options);
            console.debug("Response status:", response.status);
            
            if (!response.ok) {
                console.error("Request failed:", response.statusText);
                throw new Error(response.statusText);
            }
            
            const data = await response.json();
            console.info("Request successful, got data");
            return data;
        } catch (error) {
            console.error("Request error:", error.message);
            throw error;
        }
    }
    
    get(endpoint) {
        console.log("GET request to:", endpoint);
        return this.request(endpoint, { method: 'GET' });
    }
    
    post(endpoint, data) {
        console.log("POST request to:", endpoint);
        console.debug("POST data:", data);
        return this.request(endpoint, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
        });
    }
}

console.warn("API client module loaded");
`
        },
        {
            name: 'data-processor.js',
            content: `
// Data processing utilities
class DataProcessor {
    constructor() {
        console.log("Initializing DataProcessor");
        this.processedCount = 0;
    }
    
    processArray(data, processor) {
        console.log("Processing array with", data.length, "items");
        console.time("array-processing");
        
        const results = data.map((item, index) => {
            console.debug("Processing item", index, ":", item);
            const result = processor(item);
            this.processedCount++;
            return result;
        });
        
        console.timeEnd("array-processing");
        console.info("Array processing complete");
        console.log("Total processed so far:", this.processedCount);
        
        return results;
    }
    
    filterAndMap(data, filterFn, mapFn) {
        console.log("Filter and map operation on", data.length, "items");
        console.time("filter-map");
        
        const filtered = data.filter(item => {
            const result = filterFn(item);
            console.debug("Filter result:", result);
            return result;
        });
        
        console.log("Filtered to", filtered.length, "items");
        
        const mapped = filtered.map(item => {
            console.debug("Mapping item:", item);
            const result = mapFn(item);
            this.processedCount++;
            return result;
        });
        
        console.timeEnd("filter-map");
        console.info("Filter and map complete");
        
        return mapped;
    }
    
    async processAsync(data, asyncProcessor) {
        console.log("Async processing of", data.length, "items");
        console.time("async-processing");
        
        const promises = data.map(async (item, index) => {
            console.debug("Async processing item", index);
            try {
                const result = await asyncProcessor(item);
                this.processedCount++;
                console.debug("Async item processed:", index);
                return result;
            } catch (error) {
                console.error("Error processing item", index, ":", error.message);
                return null;
            }
        });
        
        const results = await Promise.all(promises);
        console.timeEnd("async-processing");
        console.info("Async processing complete");
        
        return results.filter(r => r !== null);
    }
    
    getStats() {
        console.info("Getting processor stats");
        return {
            processedCount: this.processedCount,
            timestamp: new Date().toISOString()
        };
    }
}

console.warn("Data processor module loaded");
`
        },
        {
            name: 'event-emitter.js',
            content: `
// Custom event emitter
class EventEmitter {
    constructor() {
        console.log("Creating EventEmitter");
        this.events = new Map();
        this.maxListeners = 10;
    }
    
    on(event, listener) {
        console.log("Adding listener for event:", event);
        if (!this.events.has(event)) {
            this.events.set(event, []);
        }
        
        const listeners = this.events.get(event);
        listeners.push(listener);
        
        console.debug("Total listeners for", event, ":", listeners.length);
        
        if (listeners.length > this.maxListeners) {
            console.warn("Possible memory leak detected for event:", event);
        }
        
        return this;
    }
    
    emit(event, ...args) {
        console.info("Emitting event:", event);
        console.debug("Event args:", args);
        
        const listeners = this.events.get(event);
        if (!listeners || listeners.length === 0) {
            console.debug("No listeners for event:", event);
            return false;
        }
        
        console.log("Notifying", listeners.length, "listeners");
        
        listeners.forEach(listener => {
            try {
                listener(...args);
            } catch (error) {
                console.error("Error in event listener:", error.message);
            }
        });
        
        return true;
    }
    
    off(event, listener) {
        console.log("Removing listener for event:", event);
        const listeners = this.events.get(event);
        
        if (listeners) {
            const index = listeners.indexOf(listener);
            if (index > -1) {
                listeners.splice(index, 1);
                console.debug("Listener removed, remaining:", listeners.length);
                return true;
            }
        }
        
        console.debug("Listener not found for event:", event);
        return false;
    }
    
    once(event, listener) {
        console.log("Adding once listener for event:", event);
        
        const onceWrapper = (...args) => {
            console.debug("Once wrapper called for event:", event);
            this.off(event, onceWrapper);
            listener(...args);
        };
        
        return this.on(event, onceWrapper);
    }
    
    removeAllListeners(event) {
        if (event) {
            console.log("Removing all listeners for event:", event);
            this.events.delete(event);
        } else {
            console.log("Removing all listeners for all events");
            this.events.clear();
        }
    }
    
    listenerCount(event) {
        const listeners = this.events.get(event);
        const count = listeners ? listeners.length : 0;
        console.debug("Listener count for", event, ":", count);
        return count;
    }
}

console.warn("Event emitter module loaded");
`
        },
        {
            name: 'logger.js',
            content: `
// Logger utility
class Logger {
    constructor(level = 'info') {
        console.log("Creating logger with level:", level);
        this.level = level;
        this.levels = {
            debug: 0,
            info: 1,
            warn: 2,
            error: 3
        };
    }
    
    debug(message, ...args) {
        console.debug("DEBUG:", message, ...args);
        this.log('debug', message, args);
    }
    
    info(message, ...args) {
        console.info("INFO:", message, ...args);
        this.log('info', message, args);
    }
    
    warn(message, ...args) {
        console.warn("WARN:", message, ...args);
        this.log('warn', message, args);
    }
    
    error(message, ...args) {
        console.error("ERROR:", message, ...args);
        this.log('error', message, args);
    }
    
    log(level, message, args) {
        const shouldLog = this.levels[level] >= this.levels[this.level];
        
        if (shouldLog) {
            const timestamp = new Date().toISOString();
            const logMessage = [timestamp, level.toUpperCase(), message, ...args].join(' ');
            
            console.log("📝", logMessage);
            
            // 这里可以添加文件日志等
            this.writeToStorage(level, logMessage);
        }
    }
    
    writeToStorage(level, message) {
        // 模拟写入存储
        console.debug("Writing to storage:", level, message);
    }
    
    setLevel(level) {
        console.log("Setting log level to:", level);
        this.level = level;
    }
    
    createChild(prefix) {
        console.log("Creating child logger with prefix:", prefix);
        return new Logger(this.level);
    }
}

console.warn("Logger module loaded");
`
        }
    ];
    
    // 写入演示文件
    demoFiles.forEach(file => {
        const filePath = path.join(demoDir, file.name);
        fs.writeFileSync(filePath, file.content);
        console.log(`✅ Created: ${file.name}`);
    });
    
    console.log(`📁 Demo files created in: ${demoDir}`);
    return demoDir;
}

async function countJsFiles(dir) {
    let count = 0;
    
    function traverse(currentDir) {
        const items = fs.readdirSync(currentDir);
        
        for (const item of items) {
            const itemPath = path.join(currentDir, item);
            const stats = fs.statSync(itemPath);
            
            if (stats.isDirectory()) {
                traverse(itemPath);
            } else if (item.endsWith('.js')) {
                count++;
            }
        }
    }
    
    traverse(dir);
    return count;
}

async function demoWithCreatedFiles() {
    const demoDir = path.join(__dirname, 'demo-files');
    
    console.log('');
    console.log('🚀 Testing parallel processing with demo files...');
    console.log('');
    
    try {
        // 使用优化处理器处理演示文件
        const { processDirectory } = require('./optimized-processor.js');
        
        const result = await processDirectory(demoDir, {
            useOllama: false,
            parallel: true,
            dryRun: false
        });
        
        console.log('');
        console.log('📊 Processing Results:');
        console.log(`   Total files: ${result.totalFiles}`);
        console.log(`   Successful: ${result.successful}`);
        console.log(`   Failed: ${result.failed}`);
        console.log(`   Processing time: ${result.processingTime}ms`);
        console.log(`   Size reduction: ${result.totalReduction} characters`);
        console.log('');
        
        if (result.successful > 0 && result.processingTime > 0) {
            const avgTime = result.processingTime / result.successful;
            console.log(`   Average time per file: ${avgTime.toFixed(1)}ms`);
            
            if (result.totalFiles >= 4) {
                console.log('✅ Parallel processing was used (≥4 files)');
            } else {
                console.log('⚠️  Single-thread processing was used (<4 files)');
            }
        }
        
    } catch (error) {
        console.error('❌ Demo processing failed:', error.message);
    } finally {
        // 清理演示文件
        console.log('');
        console.log('🧹 Cleaning up demo files...');
        if (fs.existsSync(demoDir)) {
            fs.rmSync(demoDir, { recursive: true, force: true });
        }
        console.log('✅ Demo completed!');
    }
}

// 主程序
async function main() {
    try {
        await demoParallelProcessing();
    } catch (error) {
        console.error('❌ Demo failed:', error.message);
        process.exit(1);
    }
}

if (require.main === module) {
    main().catch(console.error);
}

module.exports = { demoParallelProcessing, createDemoFiles };