"use strict";
/**
 * Vision Test Coordinator
 *
 * Orchestrates all vision-based testing agents using the Living Brain (context.json) as
 * the communication blackboard. Coordinates navigation, validation, demo recording, and
 * script generation in a cohesive workflow.
 *
 * Uses the SubAgentOrchestrator pattern for robust agent management.
 */
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.VisionTestCoordinator = void 0;
const SubAgentOrchestrator_1 = require("../orchestrator/SubAgentOrchestrator");
const VisionNavigatorAgent_1 = require("./VisionNavigatorAgent");
const VisualValidatorAgent_1 = require("./VisualValidatorAgent");
const DemoRecorderAgent_1 = require("./DemoRecorderAgent");
const VOScriptExtractorAgent_1 = require("./VOScriptExtractorAgent");
const ContextService_1 = require("../../services/ContextService");
const AICore_1 = require("../../core/ai/AICore");
const uuid_1 = require("uuid");
const chalk_1 = __importDefault(require("chalk"));
const path = __importStar(require("path"));
class VisionTestCoordinator {
    constructor() {
        this.name = "VisionTestCoordinator";
        this.description = "Master coordinator for vision-based testing workflows";
        this.personality = `You are a master coordinator overseeing an autonomous testing team.
You delegate tasks to specialized agents, monitor their progress via the Living Brain, and
ensure all pieces come together into a cohesive test execution. You're the conductor of the
vision testing orchestra.`;
        this.llmProvider = "multi"; // Uses multiple providers through agents
        this.expertise = [
            "Test orchestration",
            "Agent coordination",
            "Workflow management",
            "Result aggregation",
            "Living Brain communication",
        ];
        // Initialize orchestrator
        this.orchestrator = new SubAgentOrchestrator_1.SubAgentOrchestrator();
        // Initialize specialized agents
        this.navigatorAgent = new VisionNavigatorAgent_1.VisionNavigatorAgent();
        this.validatorAgent = new VisualValidatorAgent_1.VisualValidatorAgent();
        this.recorderAgent = new DemoRecorderAgent_1.DemoRecorderAgent();
        this.voExtractorAgent = new VOScriptExtractorAgent_1.VOScriptExtractorAgent();
        // Register agents with orchestrator
        this.orchestrator.registerAgent(this.navigatorAgent);
        this.orchestrator.registerAgent(this.validatorAgent);
        this.orchestrator.registerAgent(this.recorderAgent);
        this.orchestrator.registerAgent(this.voExtractorAgent);
    }
    async run(input) {
        const { page, browserContext, mission, projectPath } = input;
        // Initialize context service
        this.contextService = new ContextService_1.ContextService(projectPath);
        await this.contextService.initialize();
        const executionId = (0, uuid_1.v4)();
        const startTime = Date.now();
        console.log(chalk_1.default.bold.blue(`\n${"=".repeat(60)}`));
        console.log(chalk_1.default.bold.blue(`🎯 VISION TEST COORDINATOR`));
        console.log(chalk_1.default.bold.blue(`${"=".repeat(60)}\n`));
        console.log(chalk_1.default.white(`Mission: ${mission.name}`));
        console.log(chalk_1.default.gray(`ID: ${executionId}`));
        console.log(chalk_1.default.gray(`Record Demo: ${mission.recordDemo || false}\n`));
        // Write mission start to Living Brain
        await this.writeLivingBrain({
            timestamp: new Date().toISOString(),
            agentName: this.name,
            updateType: "test-start",
            data: {
                executionId,
                missionId: mission.id,
                missionName: mission.name,
                recordDemo: mission.recordDemo,
            },
            metadata: {
                testId: mission.id,
                executionId,
            },
        });
        try {
            // PHASE 1: Navigation
            console.log(chalk_1.default.bold.cyan(`\n━━━ PHASE 1: NAVIGATION ━━━`));
            const navigationResult = await this.orchestrator.executeAgent(this.navigatorAgent.name, {
                page,
                mission,
                projectPath,
                maxSteps: 20,
            });
            const steps = navigationResult.steps;
            console.log(chalk_1.default.green(`\n✓ Navigation complete: ${steps.length} steps executed`));
            // PHASE 2: Validation (if validation rules exist)
            console.log(chalk_1.default.bold.cyan(`\n━━━ PHASE 2: VALIDATION ━━━`));
            let validationResults = [];
            if (mission.validationRules &&
                mission.validationRules.length > 0) {
                // Get final screenshot
                const finalStep = steps[steps.length - 1];
                const currentScreenshot = finalStep?.screenshot || "";
                const validationOutput = await this.orchestrator.executeAgent(this.validatorAgent.name, {
                    currentScreenshot,
                    baselineScreenshot: mission.baselineScreenshots?.[0],
                    validationRules: mission.validationRules,
                    projectPath,
                    page,
                });
                validationResults = validationOutput.results;
                console.log(chalk_1.default.green(`\n✓ Validation complete: ${validationOutput.summary.passed}/${validationOutput.summary.totalChecks} passed`));
            }
            else {
                console.log(chalk_1.default.gray("  No validation rules defined, skipping..."));
            }
            // PHASE 3: Demo Recording (if requested)
            let demoArtifacts;
            if (mission.recordDemo && mission.demoConfig) {
                console.log(chalk_1.default.bold.cyan(`\n━━━ PHASE 3: DEMO RECORDING ━━━`));
                const recorderOutput = await this.orchestrator.executeAgent(this.recorderAgent.name, {
                    browserContext,
                    steps,
                    config: mission.demoConfig,
                    projectPath,
                    missionName: mission.name,
                    missionDescription: mission.description,
                });
                demoArtifacts = recorderOutput.artifacts;
                if (demoArtifacts) {
                    console.log(chalk_1.default.green(`\n✓ Demo artifacts generated in ${Object.keys(demoArtifacts.formats).length} format(s)`));
                }
                // PHASE 4: VO Script Generation (if requested)
                if (mission.demoConfig.includeVoiceOver) {
                    console.log(chalk_1.default.bold.cyan(`\n━━━ PHASE 4: VO SCRIPT GENERATION ━━━`));
                    const voScriptPath = path.join(projectPath, ".mycontext", "demos", `${mission.name}-${Date.now()}`, "voiceover-script.json");
                    const voOutput = await this.orchestrator.executeAgent(this.voExtractorAgent.name, {
                        steps,
                        missionName: mission.name,
                        missionDescription: mission.description,
                        narrationStyle: mission.demoConfig.narrationStyle,
                        projectPath,
                        outputPath: voScriptPath,
                        generateAudio: mission.demoConfig.generateAudio,
                        ttsConfig: mission.demoConfig.ttsConfig,
                    });
                    if (demoArtifacts && voOutput.success) {
                        demoArtifacts.voiceOver = {
                            script: voOutput.script,
                            audio: voOutput.audioPath
                                ? {
                                    path: voOutput.audioPath,
                                    duration: voOutput.script.totalDuration,
                                    format: "mp3",
                                }
                                : undefined,
                        };
                    }
                    console.log(chalk_1.default.green(`\n✓ Voice-over script generated with ${voOutput.script.segments.length} segments`));
                }
            }
            // Calculate final result
            const endTime = Date.now();
            const duration = endTime - startTime;
            const successfulSteps = steps.filter((s) => s.success).length;
            const passedValidations = validationResults.filter((v) => v.passed).length;
            const allStepsSuccessful = successfulSteps === steps.length;
            const allValidationsPassed = validationResults.length === 0 ||
                passedValidations === validationResults.length;
            const finalStatus = allStepsSuccessful && allValidationsPassed ? "passed" : "failed";
            // Get final URL
            const finalUrl = page.url();
            // Build test execution result
            const testResult = {
                missionId: mission.id,
                executionId,
                status: finalStatus,
                startedAt: new Date(startTime).toISOString(),
                completedAt: new Date(endTime).toISOString(),
                duration,
                steps,
                validationResults,
                finalState: {
                    url: finalUrl,
                    screenshot: steps[steps.length - 1]?.screenshot,
                },
                visualSummary: {
                    totalScreenshots: steps.filter((s) => s.screenshot).length,
                    visualRegressionsDetected: validationResults.filter((v) => !v.passed && v.rule.type?.includes("visual")).length,
                    colorSchemeMatches: validationResults.every((v) => v.passed || v.rule.type !== "color-scheme-match"),
                    layoutMatches: validationResults.every((v) => v.passed || v.rule.type !== "layout-match"),
                },
                demoArtifacts,
            };
            // Write completion to Living Brain
            await this.writeLivingBrain({
                timestamp: new Date().toISOString(),
                agentName: this.name,
                updateType: "test-complete",
                data: {
                    executionId,
                    status: finalStatus,
                    duration,
                    totalSteps: steps.length,
                    successfulSteps,
                    validationResults: validationResults.length,
                    passedValidations,
                    demoGenerated: !!demoArtifacts,
                },
                metadata: {
                    testId: mission.id,
                    executionId,
                },
            });
            // Print final summary
            console.log(chalk_1.default.bold.blue(`\n${"=".repeat(60)}`));
            console.log(chalk_1.default.bold[finalStatus === "passed" ? "green" : "red"](`${finalStatus === "passed" ? "✅ TEST PASSED" : "❌ TEST FAILED"}`));
            console.log(chalk_1.default.bold.blue(`${"=".repeat(60)}\n`));
            console.log(chalk_1.default.white(`Duration: ${(duration / 1000).toFixed(1)}s`));
            console.log(chalk_1.default.white(`Steps: ${successfulSteps}/${steps.length} successful`));
            if (validationResults.length > 0) {
                console.log(chalk_1.default.white(`Validations: ${passedValidations}/${validationResults.length} passed`));
            }
            if (demoArtifacts) {
                console.log(chalk_1.default.white(`Demo formats: ${Object.keys(demoArtifacts.formats).join(", ")}`));
            }
            console.log("");
            return {
                result: testResult,
                success: finalStatus === "passed",
            };
        }
        catch (error) {
            const endTime = Date.now();
            const duration = endTime - startTime;
            console.error(chalk_1.default.red(`\n❌ Test execution error: ${error.message}`));
            // Write error to Living Brain
            await this.writeLivingBrain({
                timestamp: new Date().toISOString(),
                agentName: this.name,
                updateType: "error",
                data: {
                    executionId,
                    error: error.message,
                    stack: error.stack,
                    duration,
                },
                metadata: {
                    testId: mission.id,
                    executionId,
                },
            });
            // Return error result
            const errorResult = {
                missionId: mission.id,
                executionId,
                status: "error",
                startedAt: new Date(startTime).toISOString(),
                completedAt: new Date(endTime).toISOString(),
                duration,
                steps: [],
                validationResults: [],
                finalState: {
                    url: page.url(),
                },
                error: {
                    message: error.message,
                    stack: error.stack,
                },
            };
            return {
                result: errorResult,
                success: false,
            };
        }
    }
    /**
     * Write update to Living Brain
     */
    async writeLivingBrain(update) {
        try {
            // Read current context using AICore
            const aiCore = AICore_1.AICore.getInstance();
            const currentContext = (await aiCore.getLivingContext()) || {};
            if (!currentContext.testExecutionHistory) {
                currentContext.testExecutionHistory = [];
            }
            currentContext.testExecutionHistory.push(update);
            // Keep only last 100 updates
            if (currentContext.testExecutionHistory.length > 100) {
                currentContext.testExecutionHistory = currentContext.testExecutionHistory.slice(-100);
            }
            // Save back to context.json using AICore
            await aiCore.saveLivingContext(currentContext);
        }
        catch (error) {
            console.warn("Failed to write to Living Brain:", error);
        }
    }
    async validate(input) {
        return !!(input.page &&
            input.browserContext &&
            input.mission &&
            input.projectPath);
    }
    async getStatus() {
        return {
            name: this.name,
            status: "idle",
            errorCount: 0,
            successCount: 0,
        };
    }
}
exports.VisionTestCoordinator = VisionTestCoordinator;
//# sourceMappingURL=VisionTestCoordinator.js.map