"use strict";
/**
 * Production Environment Validator
 * Implements AGENTS.md principle: "Fail fast, fail clearly"
 */
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 (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProductionValidator = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
class ProductionValidator {
    constructor() {
        this.errors = [];
    }
    /**
     * Validate entire production environment
     * Fails fast with clear, actionable errors
     */
    validate(options) {
        if (!options.isProduction) {
            return; // Skip validation in development
        }
        this.errors = [];
        // Check Node.js version
        this.validateNodeVersion();
        // Check write permissions
        if (options.outputPath) {
            this.validateWritePermission(options.outputPath);
        }
        // Check required paths exist
        if (options.requiredPaths) {
            this.validateRequiredPaths(options.requiredPaths);
        }
        // Check system resources
        this.validateSystemResources();
        // FAIL FAST if any errors
        if (this.errors.length > 0) {
            this.failFast();
        }
    }
    validateNodeVersion() {
        const version = process.versions.node;
        const major = Number.parseInt(version.split('.')[0], 10);
        if (major !== 20 && major !== 22 && major !== 23 && major !== 24) {
            this.errors.push({
                category: 'environment',
                message: `Invalid Node.js version: ${version}. Production requires Node.js 20.x, 22.x, 23.x, or 24.x`,
                details: { current: version, required: ['20.x', '22.x', '23.x', '24.x'] },
            });
        }
    }
    validateWritePermission(outputPath) {
        const dir = path.dirname(outputPath);
        try {
            // Create directory if it doesn't exist
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }
            // Try to create a test file
            const testFile = path.join(dir, `.somon-write-test-${Date.now()}`);
            fs.writeFileSync(testFile, 'test');
            fs.unlinkSync(testFile);
        }
        catch (error) {
            const errorCode = error instanceof Error && 'code' in error
                ? error.code
                : undefined;
            const errorMessage = error instanceof Error ? error.message : String(error);
            this.errors.push({
                category: 'permissions',
                message: `No write permission for output directory: ${dir}`,
                details: {
                    path: dir,
                    error: errorCode || errorMessage,
                },
            });
        }
    }
    validateRequiredPaths(paths) {
        for (const requiredPath of paths) {
            if (!fs.existsSync(requiredPath)) {
                this.errors.push({
                    category: 'configuration',
                    message: `Required path does not exist: ${requiredPath}`,
                    details: { path: requiredPath },
                });
            }
        }
    }
    validateSystemResources() {
        const memoryUsage = process.memoryUsage();
        // Check heap used instead of total (Node can grow heap dynamically)
        const heapUsedMB = Math.round(memoryUsage.heapUsed / 1024 / 1024);
        const minRequiredHeap = 10; // 10MB minimum heap used (reasonable for startup)
        if (heapUsedMB < minRequiredHeap && memoryUsage.heapTotal < 20 * 1024 * 1024) {
            // Only fail if both heap used is tiny AND heap total is < 20MB
            // This catches truly constrained environments
            this.errors.push({
                category: 'environment',
                message: 'Insufficient memory available',
                details: {
                    heapUsed: `${heapUsedMB}MB`,
                    heapTotal: `${Math.round(memoryUsage.heapTotal / 1024 / 1024)}MB`,
                    required: `${minRequiredHeap}MB+ heap, 20MB+ total`,
                },
            });
        }
    }
    failFast() {
        console.error('\n🚨 PRODUCTION VALIDATION FAILED\n');
        console.error('The following critical issues prevent running in production mode:\n');
        for (const error of this.errors) {
            console.error(`❌ [${error.category.toUpperCase()}] ${error.message}`);
            if (error.details) {
                console.error('   Details:', JSON.stringify(error.details, null, 2));
            }
        }
        console.error('\nPlease fix these issues before running in production mode.');
        console.error('Run without --production flag for development mode.\n');
        process.exit(1);
    }
}
exports.ProductionValidator = ProductionValidator;
//# sourceMappingURL=production-validator.js.map