#!/usr/bin/env node
/**
 * JSEye AST Parser - Extract endpoints and sinks from JavaScript using AST
 */

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

// Simple AST walker for JavaScript
function parseJavaScript(code, filename) {
    const results = {
        endpoints: [],
        sinks: [],
        secrets: [],
        functions: [],
        variables: []
    };
    
    try {
        // Basic regex-based extraction (placeholder for full AST parsing)
        
        // Extract URL patterns
        const urlPatterns = [
            /['"`]([^'"`]*\/api\/[^'"`]*)['"`]/gi,
            /['"`](https?:\/\/[^'"`]+)['"`]/gi,
            /url\s*:\s*['"`]([^'"`]+)['"`]/gi,
            /fetch\s*\(\s*['"`]([^'"`]+)['"`]/gi,
            /\.get\s*\(\s*['"`]([^'"`]+)['"`]/gi,
            /\.post\s*\(\s*['"`]([^'"`]+)['"`]/gi
        ];
        
        urlPatterns.forEach(pattern => {
            let match;
            while ((match = pattern.exec(code)) !== null) {
                results.endpoints.push({
                    url: match[1],
                    line: getLineNumber(code, match.index),
                    context: getContext(code, match.index),
                    confidence: 'medium'
                });
            }
        });
        
        // Extract potential sinks
        const sinkPatterns = [
            /\.innerHTML\s*=/gi,
            /\.outerHTML\s*=/gi,
            /document\.write\s*\(/gi,
            /eval\s*\(/gi,
            /Function\s*\(/gi,
            /location\.href\s*=/gi,
            /window\.open\s*\(/gi
        ];
        
        sinkPatterns.forEach(pattern => {
            let match;
            while ((match = pattern.exec(code)) !== null) {
                results.sinks.push({
                    type: match[0].trim(),
                    line: getLineNumber(code, match.index),
                    context: getContext(code, match.index),
                    risk: 'high'
                });
            }
        });
        
        // Extract function names
        const functionPattern = /function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/gi;
        let match;
        while ((match = functionPattern.exec(code)) !== null) {
            results.functions.push({
                name: match[1],
                line: getLineNumber(code, match.index)
            });
        }
        
    } catch (error) {
        console.error(`Error parsing ${filename}: ${error.message}`);
    }
    
    return results;
}

function getLineNumber(code, index) {
    return code.substring(0, index).split('\n').length;
}

function getContext(code, index, contextLength = 50) {
    const start = Math.max(0, index - contextLength);
    const end = Math.min(code.length, index + contextLength);
    return code.substring(start, end).replace(/\n/g, ' ').trim();
}

// Main execution
if (require.main === module) {
    const args = process.argv.slice(2);
    
    if (args.length < 1) {
        console.error('Usage: node ast_parser.js <js_file> [output_file]');
        process.exit(1);
    }
    
    const inputFile = args[0];
    const outputFile = args[1] || inputFile.replace('.js', '_ast.json');
    
    if (!fs.existsSync(inputFile)) {
        console.error(`File not found: ${inputFile}`);
        process.exit(1);
    }
    
    try {
        const code = fs.readFileSync(inputFile, 'utf8');
        const results = parseJavaScript(code, inputFile);
        
        // Add metadata
        results.metadata = {
            filename: path.basename(inputFile),
            filesize: code.length,
            lines: code.split('\n').length,
            parsed_at: new Date().toISOString()
        };
        
        // Write results
        fs.writeFileSync(outputFile, JSON.stringify(results, null, 2));
        
        console.log(`Parsed ${inputFile}:`);
        console.log(`  Endpoints: ${results.endpoints.length}`);
        console.log(`  Sinks: ${results.sinks.length}`);
        console.log(`  Functions: ${results.functions.length}`);
        console.log(`  Output: ${outputFile}`);
        
    } catch (error) {
        console.error(`Error: ${error.message}`);
        process.exit(1);
    }
}

module.exports = { parseJavaScript };