#!/usr/bin/env node

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

/**
 * 性能测试脚本 - 对比不同处理方法的性能
 */
class PerformanceTest {
    constructor() {
        this.testDir = path.join(__dirname, 'test-files');
        this.results = [];
        this.setupTestEnvironment();
    }

    /**
     * 设置测试环境
     */
    setupTestEnvironment() {
        if (!fs.existsSync(this.testDir)) {
            fs.mkdirSync(this.testDir, { recursive: true });
        }
        
        this.createTestFiles();
    }

    /**
     * 创建测试文件
     */
    createTestFiles() {
        const testFiles = [
            {
                name: 'small.js',
                content: `
function smallTest(){console.log("small test");const data={x:1,y:2};console.error("error");return data;}
console.warn("warning");
class Test{constructor(){console.debug("debug");}}
`
            },
            {
                name: 'medium.js',
                content: `
function mediumTest(){
    console.log("medium test start");
    const users = [
        {id:1,name:"Alice",console:"test"},
        {id:2,name:"Bob",age:25},
        {id:3,name:"Charlie",active:true}
    ];
    
    console.log("Processing users:", users.length);
    
    users.forEach(user => {
        console.info("Processing user:", user.name);
        user.processed = true;
    });
    
    console.debug("Processing complete");
    return users;
}

class DataProcessor {
    constructor(data) {
        console.log("DataProcessor initialized");
        this.data = data;
        console.debug("Data:", data);
    }
    
    process() {
        console.info("Starting data processing");
        console.time("processing");
        
        const result = this.data.map(item => {
            console.debug("Processing item:", item);
            return item * 2;
        });
        
        console.timeEnd("processing");
        console.log("Result:", result);
        return result;
    }
}

console.warn("Module loaded");
`
            },
            {
                name: 'large.js',
                content: `
function largeScaleProcessing(){
    console.log("Starting large scale processing");
    const startTime = Date.now();
    
    // 大量数据处理
    const data = [];
    for(let i = 0; i < 1000; i++){
        console.debug("Processing item", i);
        data.push({
            id: i,
            value: Math.random() * 100,
            timestamp: Date.now()
        });
    }
    
    console.log("Generated", data.length, "items");
    
    // 复杂处理逻辑
    const processedData = data.map((item, index) => {
        console.info("Processing item", index, "of", data.length);
        
        if(index % 100 === 0){
            console.warn("Progress checkpoint:", index);
        }
        
        return {
            ...item,
            processed: true,
            calculated: item.value * 2,
            category: item.value > 50 ? "high" : "low"
        };
    });
    
    console.timeEnd("processing");
    console.log("Processing complete in", Date.now() - startTime, "ms");
    
    // 统计分析
    const stats = {
        total: processedData.length,
        high: processedData.filter(item => item.category === "high").length,
        low: processedData.filter(item => item.category === "low").length
    };
    
    console.log("Statistics:", stats);
    console.debug("Final data sample:", processedData.slice(0, 5));
    
    return { data: processedData, stats };
}

class AnalyticsEngine {
    constructor() {
        console.log("AnalyticsEngine constructor");
        this.metrics = [];
        this.console = "property"; // 测试字符串中的console
    }
    
    track(event, data) {
        console.info("Tracking event:", event);
        const metric = {
            event,
            data,
            timestamp: Date.now()
        };
        this.metrics.push(metric);
        console.debug("Metric recorded:", metric);
    }
    
    generateReport() {
        console.log("Generating report");
        console.time("report-generation");
        
        const report = {
            totalMetrics: this.metrics.length,
            events: [...new Set(this.metrics.map(m => m.event))],
            timeRange: {
                start: Math.min(...this.metrics.map(m => m.timestamp)),
                end: Math.max(...this.metrics.map(m => m.timestamp))
            }
        };
        
        console.timeEnd("report-generation");
        console.info("Report generated:", report);
        
        return report;
    }
}

// 执行测试
console.warn("Large module loaded");
const engine = new AnalyticsEngine();
console.log("Analytics engine ready");
`
            }
        ];

        testFiles.forEach(file => {
            const filePath = path.join(this.testDir, file.name);
            if (!fs.existsSync(filePath)) {
                fs.writeFileSync(filePath, file.content);
            }
        });
    }

    /**
     * 测试方法性能
     */
    async testMethod(methodName, processFunction) {
        console.log(`\n🧪 Testing ${methodName}...`);
        
        const files = fs.readdirSync(this.testDir).filter(f => f.endsWith('.js'));
        const startTime = Date.now();
        const results = [];
        
        for (const file of files) {
            const filePath = path.join(this.testDir, file);
            const inputContent = fs.readFileSync(filePath, 'utf8');
            
            const fileStartTime = Date.now();
            
            try {
                const outputContent = await processFunction(inputContent);
                
                const fileEndTime = Date.now();
                const fileTime = fileEndTime - fileStartTime;
                
                results.push({
                    file,
                    success: true,
                    inputSize: inputContent.length,
                    outputSize: outputContent.length,
                    reduction: inputContent.length - outputContent.length,
                    time: fileTime
                });
                
                console.log(`  ✅ ${file}: ${inputContent.length}→${outputContent.length} chars (${fileTime}ms)`);
                
            } catch (error) {
                const fileEndTime = Date.now();
                const fileTime = fileEndTime - fileStartTime;
                
                results.push({
                    file,
                    success: false,
                    error: error.message,
                    time: fileTime
                });
                
                console.log(`  ❌ ${file}: ${error.message} (${fileTime}ms)`);
            }
        }
        
        const endTime = Date.now();
        const totalTime = endTime - startTime;
        
        const successful = results.filter(r => r.success);
        const totalInputSize = successful.reduce((sum, r) => sum + r.inputSize, 0);
        const totalOutputSize = successful.reduce((sum, r) => sum + r.outputSize, 0);
        const totalReduction = totalInputSize - totalOutputSize;
        
        const summary = {
            method: methodName,
            totalTime,
            files: results.length,
            successful: successful.length,
            failed: results.length - successful.length,
            totalInputSize,
            totalOutputSize,
            totalReduction,
            avgTimePerFile: totalTime / results.length
        };
        
        console.log(`📊 ${methodName} Summary:`);
        console.log(`   Total time: ${totalTime}ms`);
        console.log(`   Success rate: ${successful.length}/${results.length}`);
        console.log(`   Size reduction: ${totalReduction} chars (${((totalReduction/totalInputSize)*100).toFixed(1)}%)`);
        console.log(`   Avg time per file: ${summary.avgTimePerFile.toFixed(1)}ms`);
        
        this.results.push(summary);
        return summary;
    }

    /**
     * 正则表达式方法（快速但可能不准确）
     */
    regexMethod(input) {
        return input.replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, '');
    }

    /**
     * 状态机方法（中等速度，较准确）
     */
    stateMachineMethod(input) {
        const STATES = { NORMAL: 0, IN_STRING: 1, IN_TEMPLATE_STRING: 2, IN_REGEX: 3, IN_COMMENT: 4 };
        let state = STATES.NORMAL;
        let stringChar = '';
        let result = '';
        
        for (let i = 0; i < input.length; i++) {
            const char = input[i];
            const nextChar = input[i + 1];
            
            switch (state) {
                case STATES.NORMAL:
                    if (char === '/' && nextChar === '/') {
                        state = STATES.IN_COMMENT;
                        i++;
                    } else if (char === '/' && nextChar === '*') {
                        state = STATES.IN_COMMENT;
                        i++;
                    } else if (char === '"' || char === "'") {
                        state = STATES.IN_STRING;
                        stringChar = char;
                        result += char;
                    } else if (char === '`') {
                        state = STATES.IN_TEMPLATE_STRING;
                        result += char;
                    } else if (char === '/' && !result.match(/[a-zA-Z0-9_$]$/)) {
                        state = STATES.IN_REGEX;
                        result += char;
                    } else {
                        result += char;
                    }
                    break;
                    
                case STATES.IN_STRING:
                    result += char;
                    if (char === stringChar) {
                        state = STATES.NORMAL;
                    } else if (char === '\\') {
                        result += input[++i];
                    }
                    break;
                    
                case STATES.IN_TEMPLATE_STRING:
                    result += char;
                    if (char === '`') {
                        state = STATES.NORMAL;
                    } else if (char === '\\') {
                        result += input[++i];
                    }
                    break;
                    
                case STATES.IN_REGEX:
                    result += char;
                    if (char === '/' && !input[i-1].match(/\\/)) {
                        state = STATES.NORMAL;
                    }
                    break;
                    
                case STATES.IN_COMMENT:
                    if (char === '\n') {
                        state = STATES.NORMAL;
                        result += char;
                    } else if (char === '*' && nextChar === '/') {
                        state = STATES.NORMAL;
                        i++;
                    }
                    break;
            }
        }
        
        // 移除console语句
        return result.replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, '');
    }

    /**
     * Ollama AI方法（慢但最准确）
     */
    async ollamaMethod(input) {
        const { removeConsoleWithOllama } = require('./ollama-console-remover.js');
        return await removeConsoleWithOllama(input);
    }

    /**
     * 运行所有性能测试
     */
    async runAllTests() {
        console.log('🚀 Performance Test Suite');
        console.log('==========================');
        
        // 测试正则表达式方法
        await this.testMethod('Regex (Fast)', (input) => this.regexMethod(input));
        
        // 测试状态机方法
        await this.testMethod('State Machine (Medium)', (input) => this.stateMachineMethod(input));
        
        // 测试Ollama方法（如果可用）
        try {
            const { checkOllamaHealth } = require('./optimized-processor.js');
            const isOllamaAvailable = await checkOllamaHealth();
            
            if (isOllamaAvailable) {
                await this.testMethod('Ollama AI (Accurate)', (input) => this.ollamaMethod(input));
            } else {
                console.log('\n⚠️  Ollama not available, skipping AI method test');
                console.log('   Make sure Ollama is running: ollama serve');
                console.log('   And model is pulled: ollama pull deepseek-coder:6.7b');
            }
        } catch (error) {
            console.log('\n❌ Could not test Ollama method:', error.message);
        }
        
        this.generateReport();
    }

    /**
     * 生成性能报告
     */
    generateReport() {
        console.log('\n📈 Performance Comparison Report');
        console.log('=================================');
        
        if (this.results.length === 0) {
            console.log('No results to compare');
            return;
        }
        
        // 找出最快的和最准确的
        const fastest = this.results.reduce((min, r) => r.totalTime < min.totalTime ? r : min);
        const mostEffective = this.results.reduce((max, r) => r.totalReduction > max.totalReduction ? r : max);
        
        console.log('\n🏆 Winners:');
        console.log(`   Fastest: ${fastest.method} (${fastest.totalTime}ms)`);
        console.log(`   Most Effective: ${mostEffective.method} (${mostEffective.totalReduction} chars removed)`);
        
        console.log('\n📊 Detailed Comparison:');
        console.log('Method                 | Time (ms) | Files | Reduction | Avg/File');
        console.log('-----------------------|-----------|-------|-----------|----------');
        
        this.results.forEach(result => {
            const method = result.method.padEnd(23);
            const time = result.totalTime.toString().padStart(9);
            const files = result.successful.toString().padStart(5);
            const reduction = result.totalReduction.toString().padStart(9);
            const avgFile = result.avgTimePerFile.toFixed(1).padStart(8);
            
            console.log(`${method} | ${time} | ${files} | ${reduction} | ${avgFile}`);
        });
        
        // 保存报告
        const reportData = {
            timestamp: new Date().toISOString(),
            results: this.results,
            summary: {
                fastest: fastest.method,
                mostEffective: mostEffective.method,
                totalTests: this.results.length
            }
        };
        
        const reportPath = path.join(__dirname, 'performance-report.json');
        fs.writeFileSync(reportPath, JSON.stringify(reportData, null, 2));
        console.log(`\n💾 Detailed report saved to: ${reportPath}`);
    }
}

// 主程序
async function main() {
    const tester = new PerformanceTest();
    
    try {
        await tester.runAllTests();
    } catch (error) {
        console.error('❌ Performance test failed:', error.message);
        process.exit(1);
    }
}

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

module.exports = PerformanceTest;