"use strict";
/**
 * Next.js App Router analyzer
 * Analyzes route handlers in app directory
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeNextApp = analyzeNextApp;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const export_js_1 = require("../export.js");
const uploader_js_1 = require("../uploader.js");
/**
 * Analyze Next.js App Router routes
 */
async function analyzeNextApp(options = 'app') {
    // Support both string path and options object
    const appDir = typeof options === 'string' ? options : (options.appDir || 'app');
    const opts = typeof options === 'string' ? { projectName: '' } : options;
    const routes = [];
    try {
        const baseDir = path.join(process.cwd(), appDir);
        if (!fs.existsSync(baseDir)) {
            console.warn('app directory not found');
            return routes;
        }
        // Recursively scan for route.ts/route.js files
        const scanDir = (dir, basePath = '') => {
            const entries = fs.readdirSync(dir, { withFileTypes: true });
            for (const entry of entries) {
                const fullPath = path.join(dir, entry.name);
                if (entry.isDirectory()) {
                    // Handle dynamic routes like [id]
                    const dirName = entry.name.startsWith('[') && entry.name.endsWith(']')
                        ? `:${entry.name.slice(1, -1)}`
                        : entry.name;
                    // Skip non-route directories
                    if (['_components', '_lib', '_utils'].includes(entry.name)) {
                        continue;
                    }
                    scanDir(fullPath, `${basePath}/${dirName}`);
                }
                else if (entry.isFile() && /route\.(ts|js)$/.test(entry.name)) {
                    // Found a route file
                    const content = fs.readFileSync(fullPath, 'utf-8');
                    const methods = detectAppRouterMethods(content);
                    methods.forEach(method => {
                        routes.push({
                            method,
                            path: basePath || '/',
                            description: `${method} ${basePath || '/'}`,
                            tags: basePath.startsWith('/api') ? ['api'] : ['app'],
                            middleware: detectMiddleware(content),
                            parameters: extractParameters(basePath),
                            responses: {
                                '200': { description: 'Successful response' }
                            }
                        });
                    });
                }
            }
        };
        scanDir(baseDir);
        console.log(`✅ Found ${routes.length} routes`);
        // Export to JSON if requested
        if (opts.saveJson && opts.projectName) {
            const filePath = opts.jsonPath || 'api-export.json';
            await (0, export_js_1.exportToJSON)(routes, opts.projectName, filePath, opts.baseUrl);
        }
        // Upload to APIForge if requested
        if (opts.upload && opts.apiKey && opts.projectName) {
            await (0, uploader_js_1.uploadRoutes)(routes, {
                projectName: opts.projectName,
                apiKey: opts.apiKey,
                baseUrl: opts.baseUrl,
                apiForgeUrl: opts.apiForgeUrl
            });
        }
    }
    catch (error) {
        console.error('Error analyzing Next.js App routes:', error.message);
    }
    return routes;
}
/**
 * Detect exported HTTP method handlers
 */
function detectAppRouterMethods(content) {
    const methods = [];
    const httpMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'];
    httpMethods.forEach(method => {
        // Check for export async function METHOD or export function METHOD
        const regex = new RegExp(`export\\s+(async\\s+)?function\\s+${method}\\s*\\(`, 'g');
        if (regex.test(content)) {
            methods.push(method);
        }
    });
    return methods;
}
/**
 * Detect middleware usage
 */
function detectMiddleware(content) {
    const middleware = [];
    if (content.includes('auth') || content.includes('authenticate')) {
        middleware.push('auth');
    }
    if (content.includes('cors')) {
        middleware.push('cors');
    }
    return middleware;
}
/**
 * Extract parameters from route path
 */
function extractParameters(routePath) {
    const params = [];
    const paramMatches = routePath.match(/:(\w+)/g) || [];
    paramMatches.forEach(param => {
        const name = param.slice(1);
        params.push({
            name,
            in: 'path',
            required: true,
            type: 'string',
            description: `Path parameter: ${name}`
        });
    });
    return params;
}
