"use strict";
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;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAgenticGeneration = runAgenticGeneration;
const readline = __importStar(require("readline"));
const AgenticGenerationRunner_1 = require("../generation/AgenticGenerationRunner");
const cliLogger_1 = require("./cliLogger");
const CliTestGenerationState_1 = require("./CliTestGenerationState");
const CliStateProvider_1 = require("./CliStateProvider");
const CliTrainingContext_1 = require("./CliTrainingContext");
const CliEventHandler_1 = require("./CliEventHandler");
const ViewportStep_1 = __importStar(require("../sharedUtils/mablscript/canonical/ViewportStep"));
const VisitUrlStep_1 = __importDefault(require("../sharedUtils/mablscript/canonical/VisitUrlStep"));
const mablscriptFind_1 = require("@mablhq/test-model/mablscriptFind");
const mablscript_step_types_1 = require("../sharedUtils/mablscript-step-types");
const humanize_1 = require("../sharedUtils/mablscript/humanize");
const sessionHelpers_1 = require("./sessionHelpers");
const constants_1 = require("../../core/constants");
const chalk = require('chalk');
function createReadlineInterface() {
    return readline.createInterface({
        input: process.stdin,
        output: process.stdout,
    });
}
function printStartupInfo(resolvedSession, headless) {
    console.log(chalk.bold.cyan('Starting agentic test generation...'));
    console.log(chalk.gray('  URL:'), chalk.white(resolvedSession.url));
    console.log(chalk.gray('  Intent:'), chalk.white(resolvedSession.testIntent));
    console.log(chalk.gray('  Headless:'), chalk.white(String(headless)));
    console.log();
}
function printStepsRecursively(steps, variables, prefix = '', indent = '  ') {
    steps.forEach((step, index) => {
        const stepNumber = prefix ? `${prefix}.${index + 1}` : `${index + 1}`;
        const description = step.annotations?.description || (0, humanize_1.humanizeStepDescription)(step, variables);
        console.log(chalk.gray(`${indent}${stepNumber}.`), chalk.white(description));
        if ((0, mablscript_step_types_1.isStepGroupStep)(step) && step.stepsInGroup.length > 0) {
            printStepsRecursively(step.stepsInGroup, variables, stepNumber, indent + '  ');
        }
    });
}
function createResultProcessor() {
    return (result) => {
        const isError = result.status === 'failed';
        const statusColor = isError ? chalk.red : chalk.green;
        console.log('\n' + chalk.gray('-------------------------------------------'));
        console.log(chalk.bold.green('Generation complete!'));
        console.log(chalk.gray('  Status:'), statusColor(result.status));
        console.log(chalk.gray('  Steps generated:'), chalk.cyan(String(result.steps.length)));
        console.log(chalk.gray('-------------------------------------------') + '\n');
    };
}
async function runAgenticGeneration(options) {
    const rl = createReadlineInterface();
    try {
        let resolvedSession;
        let testName;
        let testDescription;
        if (options.type === 'existing') {
            console.log(chalk.gray('Loading existing agent session:'), chalk.white(options.agentSessionId));
            resolvedSession = await (0, sessionHelpers_1.loadAuthoringSession)(options.apiClient, options.agentSessionId);
            testName = resolvedSession.testName;
            testDescription = resolvedSession.testDescription;
        }
        else {
            console.log(chalk.gray('Creating new authoring session...'));
            const trainingSessionId = `cli-${Date.now()}`;
            resolvedSession = await (0, sessionHelpers_1.initiateAuthoringSession)(options.apiClient, {
                url: options.url,
                testIntent: options.testIntent,
                workspaceId: options.workspaceId,
                applicationId: options.applicationId,
                trainingSessionId,
            });
            testName = options.testName ?? resolvedSession.testName;
            testDescription =
                options.testDescription ?? resolvedSession.testDescription;
        }
        printStartupInfo(resolvedSession, options.headless ?? false);
        const runner = new AgenticGenerationRunner_1.AgenticGenerationRunner({
            agentSessionId: resolvedSession.sessionId,
            initialArtifacts: resolvedSession.artifacts,
            initialMessages: resolvedSession.messages,
            url: resolvedSession.url,
            testIntent: resolvedSession.testIntent,
            workspaceId: resolvedSession.workspaceId,
            applicationId: resolvedSession.applicationId,
            credentialsId: resolvedSession.credentialsId,
            credentials: options.credentials,
            testName,
            testDescription,
            viewportWidth: resolvedSession.viewportWidth,
            viewportHeight: resolvedSession.viewportHeight,
            isCloud: options.isCloud,
            headless: options.headless,
            verbose: options.verbose,
            apiClient: options.apiClient,
            appVersion: options.appVersion,
            stopCondition: 'generated-test',
            branchName: constants_1.DefaultBranchName,
            autoSave: options.autoSave,
            labels: options.labels ?? resolvedSession.labels,
            datatables: options.datatables ?? resolvedSession.datatables,
            branchId: resolvedSession.branchId,
            planId: resolvedSession.planId,
            devicePreset: resolvedSession.devicePreset,
            deviceOrientation: resolvedSession.deviceOrientation,
            scenarioId: resolvedSession.scenarioId,
            testId: resolvedSession.testId,
            existingTest: resolvedSession.existingTest,
            existingFlows: resolvedSession.existingFlows,
            proxy: options.proxy,
            shouldContinueGenerationCheck: options.shouldContinueGenerationCheck,
        }, {
            createLogger: cliLogger_1.createCliLogger,
            createState: (opts) => {
                const state = new CliTestGenerationState_1.CliTestGenerationState(opts);
                if (!resolvedSession.existingFlows?.length) {
                    const vpWidth = resolvedSession.viewportWidth ?? ViewportStep_1.DEFAULT_VIEWPORT_SIZE.width;
                    const vpHeight = resolvedSession.viewportHeight ?? ViewportStep_1.DEFAULT_VIEWPORT_SIZE.height;
                    state.addSteps([
                        new ViewportStep_1.default({ width: vpWidth, height: vpHeight }),
                        new VisitUrlStep_1.default('', {
                            name: 'web.defaults.url',
                            humanizedName: 'app.url',
                            readOnly: true,
                            variableType: mablscriptFind_1.VariableType.INPUT,
                            flowStepIndex: [],
                        }),
                    ]);
                }
                return state;
            },
            createTrainingContext: (page, browser, onNewTabDetected) => new CliTrainingContext_1.CliTrainingContext({ page, browser, onNewTabDetected }),
            createStateProvider: (state, trainingContext, flowCache, accountFeatures, snippetCache) => new CliStateProvider_1.CliStateProvider(state, trainingContext, flowCache, accountFeatures, snippetCache),
            createEventHandler: (opts) => new CliEventHandler_1.CliEventHandler({
                state: opts.state,
                trainingContext: opts.trainingContext,
                flowCache: opts.flowCache,
                stepExecutor: opts.stepExecutor,
                readlineInterface: rl,
                verbose: opts.verbose,
                outputScreenshots: options.outputScreenshots ?? false,
            }),
            processResult: createResultProcessor(),
        });
        const result = await runner.run();
        if (result.rawSteps.length > 0) {
            console.log(chalk.bold('Generated Steps:'));
            printStepsRecursively(result.rawSteps, result.variables);
            console.log();
        }
        if (result.saveResult) {
            if (result.saveResult.success) {
                console.log(chalk.green.bold('Test saved successfully!'));
                if (result.saveResult.testId) {
                    console.log(chalk.gray('  Test ID:'), chalk.white(result.saveResult.testId));
                }
                if (result.saveResult.testUrl) {
                    console.log(chalk.gray('  View:'), chalk.cyan(result.saveResult.testUrl));
                }
                console.log();
            }
            else {
                console.log(chalk.red.bold('Failed to save test:'));
                console.log(chalk.red(`  ${result.saveResult.error}`));
                console.log();
            }
        }
        return {
            success: result.success,
            steps: result.steps,
            trainingSessionId: result.trainingSessionId,
            error: result.error,
            fatalError: result.fatalError,
            rawSteps: result.rawSteps,
            saveResult: result.saveResult,
        };
    }
    finally {
        rl.close();
    }
}
