"use strict";
/**
 * @fileoverview Action functions for CLI commands.
 * Implements high-level workflows for problem template creation, test generation,
 * validation, solution execution, and full problem verification.
 * Each action corresponds to a CLI command and orchestrates multiple helper functions.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.listTestsetsAction = exports.fullVerificationAction = exports.testWhatAction = exports.runSolutionAction = exports.validateTestsAction = exports.generateTestsAction = exports.downloadTestlibAction = exports.listAvailableCheckersAction = exports.createTemplateAction = void 0;
const steps_1 = require("./steps");
const create_template_1 = require("./helpers/create-template");
const testset_1 = require("./helpers/testset");
const solution_1 = require("./helpers/solution");
const utils_1 = require("./helpers/utils");
const formatter_1 = require("./formatter");
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
/**
 * Creates a new problem template directory with all necessary files.
 * Copies template files including Config.json, Solution.cpp, Checker.cpp,
 * Generator.cpp, Validator.cpp, and directory structure.
 *
 * @param {string} directory - Name of directory to create
 *
 * @throws {Error} If directory creation fails
 * @throws {Error} If template copying fails
 *
 * @example
 * // From CLI: polyman new my-problem
 * createTemplateAction('my-problem');
 * // Creates: my-problem/ with full template structure
 */
const createTemplateAction = (directory) => {
    formatter_1.fmt.section('📁 CREATE NEW PROBLEM TEMPLATE');
    try {
        let stepNum = 1;
        // step 1: Create directory structure
        (0, steps_1.stepCreateDirectoryStructure)(stepNum++, directory);
        // step 2: Copy template files
        (0, steps_1.stepCopyTemplateFiles)(stepNum++, directory);
        // Final success message
        formatter_1.fmt.successBox('TEMPLATE CREATED SUCCESSFULLY!');
        (0, create_template_1.logTemplateCreationSuccess)(directory);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('TEMPLATE CREATION FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.createTemplateAction = createTemplateAction;
/**
 * Lists all available standard checker programs from assets/checkers directory.
 * Displays checker names and descriptions extracted from file comments.
 * Helps users choose appropriate checkers for their Config.json.
 *
 * @throws {Error} If checkers directory doesn't exist
 * @throws {Error} If reading checker files fails
 *
 * @example
 * // From CLI: polyman list-checkers
 * listAvailableCheckersAction();
 * // Displays:
 * //   1. acmp.cpp       → Almost-correct mode checker
 * //   2. fcmp.cpp       → Floating-point comparison
 * //   3. ncmp.cpp       → Number comparison
 * //   ... etc
 */
const listAvailableCheckersAction = () => {
    formatter_1.fmt.section('📋 AVAILABLE CHECKERS');
    try {
        const checkersDir = path_1.default.resolve(__dirname, '../assets/checkers');
        if (!fs_1.default.existsSync(checkersDir)) {
            throw new Error('Checkers directory not found');
        }
        const files = fs_1.default.readdirSync(checkersDir);
        const checkerFiles = files.filter(file => file.endsWith('.cpp') && file !== 'testlib.h');
        if (checkerFiles.length === 0) {
            formatter_1.fmt.warning(`${formatter_1.fmt.warningIcon()} No checker files found`);
            return;
        }
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} Found ${formatter_1.fmt.highlight(checkerFiles.length.toString())} checker(s) in ${formatter_1.fmt.dim('assets/checkers')}`);
        console.log();
        for (const [index, file] of checkerFiles.entries()) {
            const filePath = path_1.default.join(checkersDir, file);
            const content = fs_1.default.readFileSync(filePath, 'utf-8');
            const lines = content.split('\n');
            let description = 'No description available';
            for (const line of lines) {
                const trimmed = line.trim();
                if (trimmed.startsWith('// Description:')) {
                    description = trimmed.replace('// Description:', '').trim();
                    break;
                }
                if (trimmed && !trimmed.startsWith('//')) {
                    break;
                }
            }
            const checkerName = file;
            formatter_1.fmt.log(`  ${formatter_1.fmt.primary((index + 1).toString().padStart(2, ' ') + '.')} ${formatter_1.fmt.highlight(checkerName.padEnd(15))} ${formatter_1.fmt.dim('→')} ${description}`);
        }
        console.log();
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} ${formatter_1.fmt.dim(`Use these checkers in your Config.json file under the "checker" section, with ${formatter_1.fmt.highlight('isStandard: false')}.`)}`);
        console.log();
        // Listing complete
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('FAILED TO LIST CHECKERS!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.listAvailableCheckersAction = listAvailableCheckersAction;
/**
 * Downloads testlib.h from the official GitHub repository.
 * Saves the file to the current working directory and provides
 * platform-specific installation instructions for system-wide usage.
 *
 * @returns {Promise<void>} Resolves when download and save complete
 *
 * @throws {Error} If download from GitHub fails
 * @throws {Error} If file write fails
 *
 * @example
 * // From CLI: polyman download-testlib
 * await downloadTestlibAction();
 * // Downloads testlib.h to current directory
 * // Shows installation instructions for /usr/include or /usr/local/include
 */
const downloadTestlibAction = async () => {
    formatter_1.fmt.section('📥 DOWNLOAD TESTLIB.H');
    try {
        let stepNum = 1;
        // step 1: Download testlib.h
        const testlibContent = await (0, steps_1.stepDownloadTestlib)(stepNum++);
        // step 2: Save to current directory
        (0, steps_1.stepSaveTestlibToDirectory)(stepNum++, testlibContent);
        // Final success message
        formatter_1.fmt.successBox('TESTLIB.H DOWNLOADED SUCCESSFULLY!');
        console.log();
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} ${formatter_1.fmt.dim('File saved to:')} ${formatter_1.fmt.highlight(path_1.default.join(process.cwd(), 'testlib.h'))}`);
        console.log();
        // Provide installation instructions
        formatter_1.fmt.section('📝 INSTALLATION INSTRUCTIONS');
        console.log();
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} To use testlib.h system-wide, copy it to your C++ include directory:`);
        console.log();
        if (process.platform === 'win32') {
            formatter_1.fmt.log(`  ${formatter_1.fmt.dim('Windows (MinGW):')}
      ${formatter_1.fmt.primary('1.')} Find your MinGW installation directory
      ${formatter_1.fmt.primary('2.')} Copy testlib.h to: ${formatter_1.fmt.highlight('C:\\MinGW\\include\\')}
      `);
        }
        else {
            formatter_1.fmt.log(`  ${formatter_1.fmt.dim('Linux/Mac:')}
      ${formatter_1.fmt.primary('1.')} Copy to system include directory:
         ${formatter_1.fmt.highlight('sudo cp testlib.h /usr/include/')}
      ${formatter_1.fmt.primary('2.')} Or copy to local include:
         ${formatter_1.fmt.highlight('sudo cp testlib.h /usr/local/include/')}
      `);
        }
        console.log();
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} ${formatter_1.fmt.dim('After installation, you can use')} #include <testlib.h> ${formatter_1.fmt.dim('in your C++ files')}`);
        console.log();
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('TESTLIB DOWNLOAD FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.downloadTestlibAction = downloadTestlibAction;
/**
 * Generates tests based on testset/group/test specification.
 * Supports: all testsets, single testset, single group, or single test.
 *
 * @param {string} target - Target specification (testset name, group, or test index)
 * @param {string} [modifier] - Optional modifier (group name or test index)
 *
 * @throws {Error} If Config.json is invalid
 * @throws {Error} If testset/group/test not found
 * @throws {Error} If test generation fails
 *
 * @example
 * // From CLI: polyman generate all
 * await generateTestsAction('all');
 * // Generates all testsets
 *
 * @example
 * // From CLI: polyman generate tests
 * await generateTestsAction('testsets');
 * // Generates testset named 'testsets'
 *
 * @example
 * // From CLI: polyman generate tests samples
 * await generateTestsAction('testsets', 'samples');
 * // Generates group 'samples' in testset 'testsets'
 *
 * @example
 * // From CLI: polyman generate tests 5
 * await generateTestsAction('testsets', '5');
 * // Generates test 5 in testset 'testsets'
 */
const generateTestsAction = async (target, modifier) => {
    try {
        const config = (0, utils_1.readConfigFile)();
        let stepNum = 1;
        if (target === 'all') {
            // Generate all testsets
            formatter_1.fmt.section('⚙️  GENERATING ALL TESTSETS');
            // step 1: Validate configuration
            (0, steps_1.stepValidateConfigForGeneration)(stepNum++, config);
            // step 2: Compile generators
            await (0, steps_1.stepCompileGeneratorsForTestsets)(stepNum++, config);
            // step 3: Generate tests for all testsets
            await (0, steps_1.stepGenerateAllTestsets)(stepNum++, config);
            // Final success message
            formatter_1.fmt.successBox('ALL TESTSETS GENERATED!');
        }
        else {
            // Find the testset
            const testset = (0, testset_1.findTestset)(config.testsets, target);
            if (modifier && (0, utils_1.isNumeric)(modifier)) {
                // Generate single test
                const testIndex = parseInt(modifier, 10);
                formatter_1.fmt.section(`⚙️  GENERATING TEST ${testIndex} IN TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForGeneration)(stepNum++, config);
                // step 2: Compile generators
                await (0, steps_1.stepCompileGeneratorsForSingleTest)(stepNum++, config, testset, testIndex);
                // step 3: Generate test
                await (0, steps_1.stepGenerateSingleTest)(stepNum++, config, testset, testIndex);
                // Final success message
                formatter_1.fmt.successBox(`TEST ${testIndex} GENERATED IN ${target.toUpperCase()}!`);
            }
            else if (modifier) {
                // Generate group
                formatter_1.fmt.section(`⚙️  GENERATING GROUP '${modifier}' IN TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForGeneration)(stepNum++, config);
                // step 2: Compile generators
                await (0, steps_1.stepCompileGeneratorsForGroup)(stepNum++, config, testset, modifier);
                // step 3: Generate group
                await (0, steps_1.stepGenerateTestsForGroup)(stepNum++, config, testset, modifier);
                // Final success message
                formatter_1.fmt.successBox(`GROUP '${modifier}' GENERATED IN ${target.toUpperCase()}!`);
            }
            else {
                // Generate entire testset
                formatter_1.fmt.section(`⚙️  GENERATING TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForGeneration)(stepNum++, config);
                // step 2: Compile generators
                await (0, steps_1.stepCompileGeneratorsForTestset)(stepNum++, config, testset);
                // step 3: Generate tests
                await (0, steps_1.stepGenerateTestsForTestset)(stepNum++, config, testset);
                // Final success message
                formatter_1.fmt.successBox(`TESTSET ${target.toUpperCase()} GENERATED!`);
            }
        }
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('TEST GENERATION FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.generateTestsAction = generateTestsAction;
/**
 * Validates test input files using the validator program.
 * Supports validation by testset, group, or single test.
 *
 * @param {string} target - Target specification (testset name or 'all')
 * @param {string} [modifier] - Optional modifier (group name or test index)
 *
 * @throws {Error} If Config.json is invalid or missing validator
 * @throws {Error} If validator compilation fails
 * @throws {Error} If validator rejects any test
 *
 * @example
 * // From CLI: polyman validate all
 * await validateTestsAction('all');
 * // Validates all testsets
 *
 * @example
 * // From CLI: polyman validate tests
 * await validateTestsAction('testsets');
 * // Validates testset named 'testsets'
 *
 * @example
 * // From CLI: polyman validate tests samples
 * await validateTestsAction('testsets', 'samples');
 * // Validates group 'samples' in testset 'testsets'
 *
 * @example
 * // From CLI: polyman validate tests 5
 * await validateTestsAction('testsets', '5');
 * // Validates test 5 in testset 'testsets'
 */
const validateTestsAction = async (target, modifier) => {
    try {
        const config = (0, utils_1.readConfigFile)();
        let stepNum = 1;
        if (target === 'all') {
            // Validate all testsets
            formatter_1.fmt.section('✅ VALIDATING ALL TESTSETS');
            // step 1: Validate configuration
            (0, steps_1.stepValidateConfigForValidator)(stepNum++, config);
            // step 2: Compile validator
            await (0, steps_1.stepCompileValidator)(stepNum++, config);
            // step 3: Validate all testsets
            await (0, steps_1.stepValidateAllTestsets)(stepNum++, config);
            // Final success message
            formatter_1.fmt.successBox('ALL TESTSETS PASSED VALIDATION!');
        }
        else {
            // Find the testset
            const testset = (0, testset_1.findTestset)(config.testsets, target);
            if (modifier && (0, utils_1.isNumeric)(modifier)) {
                // Validate single test
                const testIndex = parseInt(modifier, 10);
                formatter_1.fmt.section(`✅ VALIDATING TEST ${testIndex} IN TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForValidator)(stepNum++, config);
                // step 2: compile validator
                await (0, steps_1.stepCompileValidator)(stepNum++, config);
                // step 3: Validate single test
                await (0, steps_1.stepValidateSingleTest)(stepNum++, config, testset.name, testIndex);
                formatter_1.fmt.successBox(`TEST ${testIndex} IN ${target.toUpperCase()} PASSED VALIDATION!`);
            }
            else if (modifier) {
                // Validate group
                formatter_1.fmt.section(`✅ VALIDATING GROUP '${modifier}' IN TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForValidator)(stepNum++, config);
                // step 2: compile validator
                await (0, steps_1.stepCompileValidator)(stepNum++, config);
                // step 3: Validate group
                await (0, steps_1.stepValidateGroup)(stepNum++, config, testset, modifier);
                formatter_1.fmt.successBox(`GROUP '${modifier}' IN ${target.toUpperCase()} PASSED VALIDATION!`);
            }
            else {
                // Validate entire testset
                formatter_1.fmt.section(`✅ VALIDATING TESTSET: ${target.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForValidator)(stepNum++, config);
                // step 2: compile validator
                await (0, steps_1.stepCompileValidator)(stepNum++, config);
                // step 3: Validate testset
                await (0, steps_1.stepValidateTestset)(stepNum++, config, testset.name);
                formatter_1.fmt.successBox(`TESTSET ${target.toUpperCase()} PASSED VALIDATION!`);
            }
        }
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('VALIDATION FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.validateTestsAction = validateTestsAction;
/**
 * Runs solution programs on test inputs based on testset/group/test specification.
 * Executes solution with time and memory limits from Config.json.
 * Saves outputs to solutions-outputs/<solution-name>/<testset>/ directory.
 *
 * @param {string} solutionName - Name of solution to run, or 'all' for all solutions
 * @param {string} target - Target specification (testset name or 'all')
 * @param {string} [modifier] - Optional modifier (group name or test index)
 *
 * @throws {Error} If Config.json is invalid or missing solutions
 * @throws {Error} If no solution matches the name
 * @throws {Error} If solution compilation fails
 * @throws {Error} If solution execution fails
 *
 * @example
 * // From CLI: polyman run-solution main all
 * await runSolutionAction('main', 'all');
 * // Runs main solution on all testsets
 *
 * @example
 * // From CLI: polyman run-solution main tests
 * await runSolutionAction('main', 'testsets');
 * // Runs main solution on testset 'testsets'
 *
 * @example
 * // From CLI: polyman run-solution main tests samples
 * await runSolutionAction('main', 'testsets', 'samples');
 * // Runs main solution on group 'samples' in testset 'testsets'
 *
 * @example
 * // From CLI: polyman run-solution main tests 5
 * await runSolutionAction('main', 'testsets', '5');
 * // Runs main solution on test 5 in testset 'testsets'
 */
const runSolutionAction = async (solutionName, target, modifier) => {
    try {
        const config = (0, utils_1.readConfigFile)();
        const matchingSolutions = (0, solution_1.findMatchingSolutions)(config.solutions, solutionName);
        let stepNum = 1;
        if (target === 'all') {
            // Run on all testsets
            formatter_1.fmt.section(`🚀 RUNNING ${solutionName.toUpperCase()} ON ALL TESTSETS`);
            // step 1: Validate configuration
            (0, steps_1.stepValidateConfigForSolutions)(stepNum++, config, matchingSolutions);
            // step 2: Compile solutions
            await (0, steps_1.stepCompileSolutions)(stepNum++, matchingSolutions);
            // step 3: Run solutions on all testsets
            await (0, steps_1.stepRunSolutionsOnAllTestsets)(stepNum++, config, matchingSolutions);
            // Final success message
            formatter_1.fmt.successBox(`${solutionName.toUpperCase()} RAN ON ALL TESTSETS!`);
        }
        else {
            // Find the testset
            const testset = (0, testset_1.findTestset)(config.testsets, target);
            if (!modifier) {
                // Run on entire testset
                formatter_1.fmt.section(`🚀 RUNNING ${solutionName.toUpperCase()} ON TESTSET: ${testset.name.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForSolutions)(stepNum++, config, matchingSolutions);
                // step 2: Compile solutions
                await (0, steps_1.stepCompileSolutions)(stepNum++, matchingSolutions);
                // step 3: Run solutions on testset
                await (0, steps_1.stepRunSolutionsOnTestset)(stepNum++, config, matchingSolutions, testset.name);
                // Final success message
                formatter_1.fmt.successBox(`${solutionName.toUpperCase()} RAN ON TESTSET ${testset.name.toUpperCase()}!`);
            }
            else if ((0, utils_1.isNumeric)(modifier)) {
                // Run on specific test
                const testIndex = parseInt(modifier, 10);
                formatter_1.fmt.section(`🚀 RUNNING ${solutionName.toUpperCase()} ON TEST ${testIndex} IN ${testset.name.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForSolutions)(stepNum++, config, matchingSolutions);
                // step 2: Compile solutions
                await (0, steps_1.stepCompileSolutions)(stepNum++, matchingSolutions);
                // step 3: Run solutions on test
                await (0, steps_1.stepRunSolutionsOnTest)(stepNum++, config, matchingSolutions, testset.name, testIndex);
                // Final success message
                formatter_1.fmt.successBox(`${solutionName.toUpperCase()} RAN ON TEST ${testIndex}!`);
            }
            else {
                // Run on specific group
                const groupName = modifier;
                formatter_1.fmt.section(`🚀 RUNNING ${solutionName.toUpperCase()} ON GROUP: ${groupName.toUpperCase()} IN ${testset.name.toUpperCase()}`);
                // step 1: Validate configuration
                (0, steps_1.stepValidateConfigForSolutions)(stepNum++, config, matchingSolutions);
                // step 2: Compile solutions
                await (0, steps_1.stepCompileSolutions)(stepNum++, matchingSolutions);
                // step 3: Run solutions on group
                await (0, steps_1.stepRunSolutionsOnGroup)(stepNum++, config, matchingSolutions, testset, groupName);
                // Final success message
                formatter_1.fmt.successBox(`${solutionName.toUpperCase()} RAN ON GROUP ${groupName.toUpperCase()}!`);
            }
        }
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('SOLUTION EXECUTION FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.runSolutionAction = runSolutionAction;
/**
 * Tests validator, checker, or solution programs.
 * For validator/checker: Runs self-tests from their test configuration.
 * For solutions: Tests against main-correct solution using checker.
 *
 * @param {string} what - 'validator', 'checker', or solution name to test
 * @returns {Promise<void>} Resolves when testing completes
 *
 * @throws {Error} If Config.json is invalid
 * @throws {Error} If validator/checker tests fail
 * @throws {Error} If solution doesn't exist
 * @throws {Error} If main-correct solution doesn't exist
 * @throws {Error} If solution behavior doesn't match expected type
 *
 * @example
 * // From CLI: polyman test validator
 * await testWhatAction('validator');
 * // Runs validator self-tests from validator_tests.json
 *
 * @example
 * // From CLI: polyman test checker
 * await testWhatAction('checker');
 * // Runs checker self-tests from checker_tests.json
 *
 * @example
 * // From CLI: polyman test wa-solution
 * await testWhatAction('wa-solution');
 * // Runs wa-solution and main solution, compares with checker
 * // Validates that wa-solution gets WA on at least one test
 */
const testWhatAction = async (what) => {
    formatter_1.fmt.section(`🔍 TESTING: ${what.toUpperCase()}`);
    try {
        let stepNum = 1;
        switch (what) {
            case 'validator':
                {
                    const config = (0, utils_1.readConfigFile)();
                    // step 1: Validate configuration
                    (0, steps_1.stepValidateConfigForValidator)(stepNum++, config);
                    // step 2: Compile validator
                    await (0, steps_1.stepCompileValidator)(stepNum++, config);
                    // step 3: Run validator self-tests
                    await (0, steps_1.stepTestValidator)(stepNum++);
                }
                formatter_1.fmt.successBox('VALIDATOR TESTS PASSED!');
                break;
            case 'checker':
                {
                    const config = (0, utils_1.readConfigFile)();
                    // step 1: Validate configuration
                    (0, steps_1.stepValidateConfigForChecker)(stepNum++, config);
                    // step 2: Compile checker
                    await (0, steps_1.stepCompileChecker)(stepNum++, config);
                    // step 3: Run checker self-tests
                    await (0, steps_1.stepTestChecker)(stepNum++);
                }
                formatter_1.fmt.successBox('CHECKER TESTS PASSED!');
                break;
            default: {
                // Testing a solution against main-correct
                // step 1: Validate configuration
                const { mainSolution, targetSolution } = (0, steps_1.stepValidateConfigForSolutionTest)(stepNum++, what);
                // step 2: Compile solutions
                await (0, steps_1.stepCompileSolutions)(stepNum++, [mainSolution, targetSolution]);
                // step 3: Compile checker
                {
                    const config = (0, utils_1.readConfigFile)();
                    await (0, steps_1.stepCompileChecker)(stepNum++, config);
                }
                // step 4: Test solution behavior
                await (0, steps_1.stepTestSolutionBehavior)(stepNum++, what);
                // Final success message
                formatter_1.fmt.successBox(`${what.toUpperCase()} BEHAVES AS EXPECTED!`);
                break;
            }
        }
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('TESTING FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.testWhatAction = testWhatAction;
/**
 * Performs complete problem verification workflow.
 * Executes all steps: test generation, validator testing, test validation,
 * checker testing, solution execution, and solution verification.
 * This is the main command for validating a complete Polygon problem package.
 *
 * Verification steps:
 * 1. Generate all tests using generators
 * 2. Run validator self-tests
 * 3. Validate all generated tests
 * 4. Run checker self-tests
 * 5. Execute all solutions on all tests
 * 6. Verify each solution behaves according to its type (TLE, WA, etc.)
 *
 * @returns {Promise<void>} Resolves when full verification completes
 *
 * @throws {Error} If Config.json is invalid
 * @throws {Error} If any verification step fails
 * @throws {Error} If generators, validator, checker, or solutions are missing
 * @throws {Error} If main-correct solution doesn't exist
 * @throws {Error} If any solution behaves unexpectedly
 *
 * @example
 * // From CLI: polyman verify
 * await fullVerificationAction();
 * // Runs complete verification workflow:
 * // - Generates tests
 * // - Validates tests
 * // - Tests checker
 * // - Runs all solutions
 * // - Verifies all solutions against main-correct
 */
const fullVerificationAction = async () => {
    formatter_1.fmt.section('🏆 POLYGON PROBLEM VERIFICATION');
    try {
        const config = (0, utils_1.readConfigFile)();
        let stepNum = 1;
        // step 1: Compile generators
        await (0, steps_1.stepCompileGeneratorsForTestsets)(stepNum++, config);
        // step 2: Generate tests
        await (0, steps_1.stepGenerateTestsForVerification)(stepNum++, config);
        // step 3: Compile validator
        await (0, steps_1.stepCompileValidator)(stepNum++, config);
        // step 4: Test validator
        await (0, steps_1.stepTestValidator)(stepNum++);
        // step 5: Validate generated tests
        await (0, steps_1.stepValidateGeneratedTests)(stepNum++, config);
        // step 6: Compile checker
        await (0, steps_1.stepCompileChecker)(stepNum++, config);
        // step 7: Test checker
        await (0, steps_1.stepTestChecker)(stepNum++);
        // step 8: Compile solutions
        await (0, steps_1.stepCompileSolutionsForVerification)(stepNum++, config);
        // step 9: Run solutions
        await (0, steps_1.stepRunSolutionsForVerification)(stepNum++, config);
        // step 10: Verify solutions against main correct
        await (0, steps_1.stepVerifySolutionsAgainstMainCorrect)(stepNum++, config);
        // Final success message
        formatter_1.fmt.successBox('🎉 FULL VERIFICATION COMPLETE!');
        console.log();
        formatter_1.fmt.success(`  ${formatter_1.fmt.checkmark()} All components tested and verified successfully`);
        console.log();
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('VERIFICATION FAILED!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.fullVerificationAction = fullVerificationAction;
/**
 * Lists all available testsets in the configuration.
 * Shows testset names, number of tests, and groups.
 *
 * @returns {Promise<void>} Resolves when listing completes
 *
 * @throws {Error} If Config.json is invalid or missing testsets
 *
 * @example
 * // From CLI: polyman list-testsets
 * await listTestsetsAction();
 * // Displays:
 * //   1. tests: 15 tests, groups: samples, main
 * //   2. stress: 100 tests, groups: none
 */
const listTestsetsAction = () => {
    formatter_1.fmt.section('📋 AVAILABLE TESTSETS');
    try {
        const config = (0, utils_1.readConfigFile)();
        const descriptions = (0, testset_1.listTestsets)(config.testsets);
        formatter_1.fmt.info(`  ${formatter_1.fmt.infoIcon()} Found ${formatter_1.fmt.highlight(config.testsets.length.toString())} testset(s)`);
        console.log();
        for (const [index, description] of descriptions.entries()) {
            formatter_1.fmt.log(`  ${formatter_1.fmt.primary((index + 1).toString().padStart(2, ' ') + '.')} ${description}`);
        }
        console.log();
        // Listing complete
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        formatter_1.fmt.errorBox('FAILED TO LIST TESTSETS!');
        formatter_1.fmt.error(`${message}`);
        console.log();
        process.exit(1);
    }
};
exports.listTestsetsAction = listTestsetsAction;
// export const registerApiKeyAndSecret = async (
//   apiKey: string,
//   secret: string
// ) => {
//   try {
//   } catch (error) {
//     logErrorAndExit(error);
//   }
// };
//# sourceMappingURL=actions.js.map