#!/usr/bin/env node

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

// Ollama配置
const OLLAMA_CONFIG = {
    baseUrl: 'http://localhost:11434',
    model: 'deepseek-coder:6.7b',
    timeout: 30000 // 30秒超时
};

/**
 * 使用Ollama API处理JavaScript代码，去除console语句
 * @param {string} jsCode 原始JavaScript代码
 * @returns {Promise<string>} 处理后的代码
 */
async function removeConsoleWithOllama(jsCode) {
    const prompt = `Please remove all console statements from this JavaScript code while preserving the code structure and functionality. Only remove console.log, console.error, console.warn, console.info, console.debug, console.assert, console.trace, console.table, console.group, console.groupEnd, console.time, console.timeEnd calls. Return only the cleaned code without any explanations.

JavaScript code:
\`\`\`javascript
${jsCode}
\`\`\`

Cleaned code:`;

    try {
        const response = await fetch(`${OLLAMA_CONFIG.baseUrl}/api/generate`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                model: OLLAMA_CONFIG.model,
                prompt: prompt,
                stream: false,
                options: {
                    temperature: 0.1, // 低温度确保一致性
                    top_p: 0.9,
                    max_tokens: 8000
                }
            })
        });

        if (!response.ok) {
            throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        
        if (!data.response) {
            throw new Error('No response from Ollama');
        }

        // 提取返回的代码（去除可能的markdown标记）
        let cleanedCode = data.response.trim();
        
        // 去除可能的代码块标记
        if (cleanedCode.startsWith('```')) {
            const lines = cleanedCode.split('\n');
            if (lines[0].includes('javascript')) {
                lines.shift(); // 移除 ```javascript
            } else {
                lines.shift(); // 移除 ```
            }
            if (lines[lines.length - 1] === '```') {
                lines.pop(); // 移除结尾的 ```
            }
            cleanedCode = lines.join('\n');
        }

        return cleanedCode;
    } catch (error) {
        console.error('Error calling Ollama API:', error.message);
        throw error;
    }
}

/**
 * 检查Ollama服务是否可用
 * @returns {Promise<boolean>}
 */
async function checkOllamaHealth() {
    try {
        const response = await fetch(`${OLLAMA_CONFIG.baseUrl}/api/tags`, {
            signal: AbortSignal.timeout(5000)
        });
        return response.ok;
    } catch (error) {
        return false;
    }
}

/**
 * 递归处理目录中的所有JS文件
 * @param {string} inputDir 输入目录
 * @param {string} outputDir 输出目录
 * @param {boolean} useOllama 是否使用Ollama
 * @param {boolean} dryRun 是否只是预览模式
 */
async function processJsFiles(inputDir, outputDir, useOllama = true, dryRun = false) {
    if (!fs.existsSync(outputDir) && !dryRun) {
        fs.mkdirSync(outputDir, { recursive: true });
    }

    const items = fs.readdirSync(inputDir);
    
    for (const item of items) {
        const inputPath = path.join(inputDir, item);
        const outputPath = path.join(outputDir, item);
        const stats = fs.statSync(inputPath);

        if (stats.isDirectory()) {
            // 递归处理子目录
            await processJsFiles(inputPath, outputPath, useOllama, dryRun);
        } else if (path.extname(item) === '.js') {
            // 处理JS文件
            console.log(`Processing: ${inputPath}`);
            
            try {
                const originalCode = fs.readFileSync(inputPath, 'utf8');
                let cleanedCode;

                if (useOllama) {
                    console.log(`  Using Ollama to process ${item}...`);
                    cleanedCode = await removeConsoleWithOllama(originalCode);
                } else {
                    console.log(`  Ollama not available, using fallback method for ${item}...`);
                    cleanedCode = removeConsoleFallback(originalCode);
                }

                if (!dryRun) {
                    fs.writeFileSync(outputPath, cleanedCode, 'utf8');
                    console.log(`  ✅ Saved: ${outputPath}`);
                } else {
                    console.log(`  🔍 [Dry Run] Would save to: ${outputPath}`);
                    console.log(`  Original size: ${originalCode.length} chars`);
                    console.log(`  Cleaned size: ${cleanedCode.length} chars`);
                    console.log(`  Size reduction: ${originalCode.length - cleanedCode.length} chars`);
                }

            } catch (error) {
                console.error(`  ❌ Error processing ${item}:`, error.message);
                if (!dryRun) {
                    // 发生错误时复制原文件
                    fs.copyFileSync(inputPath, outputPath);
                    console.log(`  📋 Copied original file due to error`);
                }
            }
        } else {
            // 复制非JS文件
            if (!dryRun) {
                fs.copyFileSync(inputPath, outputPath);
                console.log(`📋 Copied: ${inputPath}`);
            }
        }
    }
}

/**
 * 备用的console移除方法（本地处理）
 * @param {string} jsCode JavaScript代码
 * @returns {string} 处理后的代码
 */
function removeConsoleFallback(jsCode) {
    // 简单的正则表达式方法（可能有误判，仅作为备用）
    return jsCode
        .replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, '')
        .replace(/\/\*[\s\S]*?\*\//g, '') // 移除多行注释
        .replace(/\/\/.*$/gm, ''); // 移除单行注释
}

/**
 * 显示帮助信息
 */
function showHelp() {
    console.log(`
Usage: node ollama-console-remover.js [options] <input-directory> [output-directory]

Arguments:
  input-directory    Directory containing JavaScript files to process
  output-directory    Directory to save processed files (default: input-directory + '-cleaned')

Options:
  --local, -l         Use local fallback method instead of Ollama
  --dry-run, -d       Preview mode - don't save files, just show what would be done
  --help, -h          Show this help message

Examples:
  # Process JS files in ./dist directory, save to ./dist-cleaned
  node ollama-console-remover.js ./dist

  # Process JS files, save to specific output directory
  node ollama-console-remover.js ./dist ./cleaned-dist

  # Use local fallback method (don't use Ollama)
  node ollama-console-remover.js --local ./dist

  # Dry run - just see what would be processed
  node ollama-console-remover.js --dry-run ./dist

Note:
  This script requires Ollama to be running with deepseek-coder:6.7b model.
  Make sure Ollama is installed and the model is pulled:
  ollama pull deepseek-coder:6.7b
`);
}

/**
 * 主函数
 */
async function main() {
    const args = process.argv.slice(2);
    
    // 解析参数
    let useOllama = true;
    let dryRun = false;
    let inputDir = '';
    let outputDir = '';

    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        
        if (arg === '--help' || arg === '-h') {
            showHelp();
            return;
        } else if (arg === '--local' || arg === '-l') {
            useOllama = false;
        } else if (arg === '--dry-run' || arg === '-d') {
            dryRun = true;
        } else if (!inputDir) {
            inputDir = arg;
        } else if (!outputDir) {
            outputDir = arg;
        }
    }

    if (!inputDir) {
        console.error('Error: Input directory is required');
        showHelp();
        process.exit(1);
    }

    if (!fs.existsSync(inputDir)) {
        console.error(`Error: Input directory "${inputDir}" does not exist`);
        process.exit(1);
    }

    if (!outputDir) {
        outputDir = inputDir + '-cleaned';
    }

    console.log(`🚀 Starting JS console removal...`);
    console.log(`📂 Input directory: ${inputDir}`);
    console.log(`📁 Output directory: ${outputDir}`);
    console.log(`🤖 Using Ollama: ${useOllama ? 'Yes' : 'No (local fallback)'}`);
    console.log(`🔍 Dry run: ${dryRun ? 'Yes' : 'No'}`);
    console.log('');

    // 检查Ollama服务
    if (useOllama) {
        console.log('🔍 Checking Ollama service...');
        const isOllamaAvailable = await checkOllamaHealth();
        
        if (!isOllamaAvailable) {
            console.log('⚠️  Ollama service is not available, switching to local fallback method');
            useOllama = false;
        } else {
            console.log('✅ Ollama service is available');
        }
    }

    try {
        await processJsFiles(inputDir, outputDir, useOllama, dryRun);
        
        console.log('');
        if (dryRun) {
            console.log('🔍 Dry run completed!');
        } else {
            console.log('✅ All files processed successfully!');
            console.log(`📁 Cleaned files saved to: ${outputDir}`);
        }
    } catch (error) {
        console.error('❌ Error during processing:', error.message);
        process.exit(1);
    }
}

// 执行主函数
if (require.main === module) {
    main().catch(console.error);
}

module.exports = {
    removeConsoleWithOllama,
    checkOllamaHealth,
    processJsFiles
};