"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const env_1 = require("@mablhq-internal/runtime/env/env");
const cliUtil_1 = require("@mablhq-internal/runtime/core/cliUtil");
const testsUtil_1 = require("@mablhq-internal/runtime/core/execution/testsUtil");
const constants_1 = require("../../constants");
const constants_2 = require("@mablhq-internal/runtime/core/constants");
const trainingSessions_1 = require("@mablhq-internal/runtime/core/trainer/trainingSessions");
const mablApiClientFactory_1 = require("@mablhq-internal/runtime/api/mablApiClientFactory");
const runAgenticGeneration_1 = require("@mablhq-internal/runtime/trainer/cli/runAgenticGeneration");
const runCloudTestGeneration_1 = require("@mablhq-internal/runtime/trainer/cli/runCloudTestGeneration");
const pureUtil_1 = require("@mablhq-internal/runtime/util/pureUtil");
const postGeneration_1 = require("./postGeneration");
const chalk = require('chalk');
const CommandArgAutoSave = 'save';
const CommandArgMode = 'mode';
const CommandArgSnapshot = 'snapshot';
exports.command = 'edit';
exports.describe = 'Edit a browser test';
exports.builder = (yargs) => {
    yargs
        .example('$0 tests edit --id <id>', 'edit test in the Trainer by id')
        .example('$0 tests edit --run-id <test-run-id>', 'edit a browser test in the Trainer in the context of a test configuration from a cloud run')
        .option(constants_2.CommandArgId, {
        describe: 'the id of the test to edit',
        type: 'string',
    })
        .option(constants_2.CommandArgTestRunId, {
        describe: 'The id of the test run to pull config from',
        type: 'string',
    })
        .option(constants_2.CommandArgMablBranch, {
        describe: 'Branch to edit the mabl test against',
        nargs: 1,
        type: 'string',
    })
        .option(constants_1.CommandArgMablAutoBranch, {
        describe: 'Create a mabl branch when a mabl-branch target is specified that does not exist',
        type: 'boolean',
        default: false,
    })
        .option(constants_2.CommandArgEnvironmentId, {
        alias: constants_1.CommandArgAliases.EnvironmentId,
        describe: 'Mabl environment to edit the test under. Specify to edit the test with environment variables and the latest find information.',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgApplicationId, {
        alias: constants_1.CommandArgAliases.ApplicationId,
        describe: 'Mabl application to edit the test under',
        nargs: 1,
        type: 'string',
    })
        .option('width', {
        describe: 'Set the browser width in pixels',
        default: constants_1.DEFAULT_BROWSER_WIDTH,
        nargs: 1,
        type: 'number',
    })
        .option('height', {
        describe: 'Set the browser height in pixels',
        default: constants_1.DEFAULT_BROWSER_HEIGHT,
        nargs: 1,
        type: 'number',
    })
        .option(constants_2.CommandArgUrl, {
        alias: constants_1.CommandArgAliases.Url,
        describe: 'URL to edit the mabl test against',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgCredentials, {
        alias: constants_1.CommandArgAliases.Credentials,
        describe: 'Credentials ID to edit the test with',
        nargs: 1,
        type: 'string',
    })
        .option(constants_1.CommandArgBrowserDisableIsolation, {
        hidden: true,
        describe: 'Disable cross origin isolation',
        default: false,
        type: 'boolean',
    })
        .option(constants_1.CommandArgBrowserIgnoreCertificateErrors, {
        hidden: true,
        describe: 'Ignore certificate errors',
        default: false,
        type: 'boolean',
    })
        .option(constants_1.CommandArgIntent, {
        hidden: true,
        describe: 'The change to make to the test for agentic test editing. When provided, enables agentic edit mode.',
        nargs: 1,
        type: 'string',
    })
        .option(constants_1.CommandArgHeadless, {
        hidden: true,
        describe: 'Run browser in headless mode during agentic editing',
        type: 'boolean',
        default: false,
    })
        .option(constants_1.CommandArgVerbose, {
        hidden: true,
        describe: 'Enable verbose logging for agentic editing',
        type: 'boolean',
        default: false,
    })
        .option(CommandArgAutoSave, {
        hidden: true,
        describe: 'Automatically save the test after agentic editing',
        type: 'boolean',
        default: false,
    })
        .option(constants_1.CommandArgOutputScreenshots, {
        hidden: true,
        describe: 'Output base64-encoded screenshots to stdout during editing',
        type: 'boolean',
        default: false,
    })
        .option(CommandArgMode, {
        hidden: true,
        describe: 'Edit generation mode: "local" runs locally (default), "cloud" runs in the mabl cloud and returns session/instance IDs for polling status.',
        type: 'string',
        choices: ['local', 'cloud'],
        default: 'local',
    });
    if (env_1.ENV !== 'prod') {
        yargs.option(CommandArgSnapshot, {
            hidden: true,
            describe: 'Pin cloud test generation to a specific snapshot image. Pass the 7-char short commit hash of the target build (e.g. --snapshot abc1234).',
            type: 'string',
        });
    }
    yargs.check((argv) => (0, testsUtil_1.validateRunEditCommand)(argv[constants_2.CommandArgId], argv[constants_2.CommandArgTestRunId]));
};
exports.handler = (0, cliUtil_1.failWrapper)(launchEditTrainingSession);
async function launchEditTrainingSession(parsed) {
    const testRunId = parsed['run-id'];
    const testId = parsed.id;
    const url = parsed.url;
    const credentialsId = parsed['credentials-id'];
    const branchName = parsed['mabl-branch'];
    const width = parsed.width;
    const height = parsed.height;
    const autoBranch = parsed['auto-branch'];
    const environmentId = parsed[constants_2.CommandArgEnvironmentId];
    const applicationId = parsed[constants_2.CommandArgApplicationId];
    const disableIsolation = parsed[constants_1.CommandArgBrowserDisableIsolation];
    const ignoreCertificateErrors = parsed[constants_1.CommandArgBrowserIgnoreCertificateErrors];
    const testIntent = parsed[constants_1.CommandArgIntent];
    if (testIntent) {
        await runAgenticEdit(parsed, testIntent);
        return 'done';
    }
    const editTrainingSessionOptions = {
        applicationId,
        autoBranch,
        branchName,
        credentialsId,
        disableIsolation,
        environmentId,
        height,
        ignoreCertificateErrors,
        testId,
        testRunId,
        url,
        width,
    };
    await (0, trainingSessions_1.editTest)(editTrainingSessionOptions);
    return 'done';
}
async function runAgenticEdit(parsed, testIntent) {
    const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
    let testId = parsed.id;
    let branchName = parsed['mabl-branch'];
    if (!testId && parsed['run-id']) {
        const runConfig = await (0, testsUtil_1.pullDownTestRunConfig)(parsed['run-id'], apiClient);
        testId = runConfig.testId;
        branchName = branchName ?? runConfig.branchName;
    }
    if (!testId) {
        throw new Error('Unable to determine the test to edit. Provide --id or --run-id.');
    }
    const test = await apiClient.getJourney(testId, branchName ?? constants_2.DefaultBranchName);
    const workspaceId = test.organization_id;
    if (!workspaceId) {
        throw new Error(`Could not determine the workspace for test ${testId}.`);
    }
    const features = await apiClient.getEnabledAccountFeaturesByWorkspaceId(workspaceId);
    if (!features.hasAgenticTestEditing()) {
        throw new Error('Agentic test editing is not enabled for your account. Contact your workspace owner or mabl support to enable the "agentic_test_editing" feature.');
    }
    const applicationId = parsed[constants_2.CommandArgApplicationId];
    if (parsed[CommandArgMode] === 'cloud') {
        console.log(chalk.cyan('Initiating cloud test editing...'));
        const result = await (0, runCloudTestGeneration_1.runCloudTestGeneration)({
            url: parsed.url ?? test.url ?? '',
            testName: test.name ?? '',
            workspaceId,
            environmentId: parsed[constants_2.CommandArgEnvironmentId] ?? '',
            applicationId: applicationId ?? test.application_id,
            credentialsId: parsed['credentials-id'] ?? test.credentials_id,
            testIntent,
            snapshot: parsed[CommandArgSnapshot],
            testId,
            branchId: branchName,
        }, apiClient);
        console.log(chalk.green('\nCloud test editing initiated successfully!'));
        console.log(chalk.gray('  Session ID:'), chalk.white(result.sessionId));
        if (result.instanceId) {
            console.log(chalk.gray('  Instance ID:'), chalk.white(result.instanceId));
        }
        const statusCommand = `mabl tests cloud-status --session-id ${result.sessionId}${result.instanceId ? ` --instance-id ${result.instanceId}` : ''}`;
        console.log(chalk.gray('\n  Check status with:'), chalk.cyan(statusCommand));
        return;
    }
    const result = await (0, runAgenticGeneration_1.runAgenticGeneration)({
        type: 'edit',
        testId,
        testIntent,
        workspaceId,
        applicationId,
        branchId: branchName,
        headless: parsed[constants_1.CommandArgHeadless] ?? false,
        verbose: parsed[constants_1.CommandArgVerbose] ?? false,
        apiClient,
        appVersion: (0, pureUtil_1.getCliVersion)(),
        autoSave: parsed[CommandArgAutoSave],
        outputScreenshots: parsed[constants_1.CommandArgOutputScreenshots] ?? false,
        enableSaveConflictResolution: true,
    });
    if (!result.success) {
        throw new Error(`Agentic test editing failed: ${result.error}`);
    }
    console.log('\nTest editing completed successfully!');
    console.log(`Training Session ID: ${result.trainingSessionId}`);
    console.log(`Steps: ${result.steps.length}`);
    if (result.saveResult?.success) {
        console.log(chalk.green('\n✓ Test saved successfully!'));
        console.log(chalk.gray('  Test ID:'), chalk.white(result.saveResult.testId));
        console.log(chalk.gray('  View:'), chalk.cyan(result.saveResult.testUrl));
        return;
    }
    if (result.saveResult?.error) {
        console.error(chalk.red('\n✗ Auto-save failed:'), result.saveResult.error);
    }
    await (0, postGeneration_1.handlePostGenerationActions)({
        workspaceId,
        applicationId,
        url: result.existingTest?.url ?? parsed.url ?? '',
        testName: result.existingTest?.name ?? '',
        testIntent,
        apiClient,
        result,
        autoSave: false,
        existingTest: result.existingTest,
        branchId: branchName,
        entityVersion: result.entityVersion,
    });
}
