"use strict";
/**
 * Progress Tracking System
 *
 * Manages granular progress tracking for build-app workflow.
 * Generates JSON files that can be consumed by VS Code extension,
 * web dashboard, or other external tools.
 */
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.ProgressTracker = void 0;
const fs = __importStar(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
class ProgressTracker {
    constructor(projectPath) {
        this.phaseStartTimes = new Map();
        this.stepStartTimes = new Map();
        this.projectPath = projectPath;
        this.progressDir = path_1.default.join(projectPath, ".mycontext", "progress");
        this.masterProgress = this.initializeMasterProgress();
    }
    initializeMasterProgress() {
        return {
            version: "2.0.8",
            startTime: new Date().toISOString(),
            endTime: null,
            status: "pending",
            currentPhase: "preflight",
            currentStep: 0,
            totalSteps: 230,
            percentComplete: 0,
            phases: {
                preflight: this.createPhaseProgress(10),
                initialization: this.createPhaseProgress(15),
                context_generation: this.createPhaseProgress(25),
                types: this.createPhaseProgress(10),
                branding: this.createPhaseProgress(10),
                build_strategy: this.createPhaseProgress(10),
                component_list: this.createPhaseProgress(10),
                component_generation: this.createPhaseProgress(0), // Dynamic based on component count
                server_actions: this.createPhaseProgress(30),
                routes: this.createPhaseProgress(20),
                integration: this.createPhaseProgress(20),
                post_generation: this.createPhaseProgress(10),
            },
            errors: [],
            retries: {
                total: 0,
                byPhase: {},
            },
            userInteractions: 0,
            buildChecks: {
                typescript: { passed: 0, failed: 0 },
                eslint: { passed: 0, failed: 0 },
                build: { passed: 0, failed: 0 },
                tests: { passed: 0, failed: 0 },
            },
        };
    }
    createPhaseProgress(steps) {
        return {
            status: "pending",
            steps,
            completedSteps: 0,
            duration: 0,
        };
    }
    async initialize() {
        await fs.ensureDir(this.progressDir);
        await fs.ensureDir(path_1.default.join(this.progressDir, "07-components"));
        await this.saveMasterProgress();
    }
    async startPhase(phaseName) {
        this.masterProgress.currentPhase = phaseName;
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            phase.status = "in_progress";
            phase.startTime = new Date().toISOString();
        }
        this.phaseStartTimes.set(phaseName, Date.now());
        console.log(chalk_1.default.blue(`\n📋 Phase Started: ${this.formatPhaseName(phaseName)}`));
        await this.saveMasterProgress();
    }
    async completePhase(phaseName) {
        const startTime = this.phaseStartTimes.get(phaseName);
        const duration = startTime ? Date.now() - startTime : 0;
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            phase.status = "completed";
            phase.endTime = new Date().toISOString();
            phase.duration = duration;
            phase.completedSteps = phase.steps;
        }
        console.log(chalk_1.default.green(`✅ Phase Completed: ${this.formatPhaseName(phaseName)} (${Math.round(duration / 1000)}s)`));
        await this.saveMasterProgress();
    }
    async failPhase(phaseName, error) {
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            phase.status = "failed";
        }
        this.masterProgress.errors.push({
            phase: phaseName,
            step: this.masterProgress.currentStep,
            error,
            timestamp: new Date().toISOString(),
        });
        console.log(chalk_1.default.red(`❌ Phase Failed: ${this.formatPhaseName(phaseName)}`));
        await this.saveMasterProgress();
    }
    async requestValidation(phaseName, validationType) {
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            phase.status = "validation_required";
        }
        this.masterProgress.status = "validation_required";
        this.masterProgress.userInteractions++;
        console.log(chalk_1.default.yellow(`\n⏸️  Validation Required: ${validationType}`));
        await this.saveMasterProgress();
    }
    async approveValidation(phaseName, validationType) {
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            if (!phase.userValidations) {
                phase.userValidations = {};
            }
            phase.userValidations[validationType] = true;
            phase.status = "in_progress";
        }
        this.masterProgress.status = "in_progress";
        console.log(chalk_1.default.green(`✅ Validation Approved: ${validationType}`));
        await this.saveMasterProgress();
    }
    async incrementStep(phaseName) {
        this.masterProgress.currentStep++;
        const phase = this.masterProgress.phases[phaseName];
        if (phase) {
            phase.completedSteps++;
        }
        this.masterProgress.percentComplete =
            (this.masterProgress.currentStep / this.masterProgress.totalSteps) * 100;
        await this.saveMasterProgress();
    }
    async recordBuildCheck(type, passed) {
        if (passed) {
            this.masterProgress.buildChecks[type].passed++;
        }
        else {
            this.masterProgress.buildChecks[type].failed++;
        }
        await this.saveMasterProgress();
    }
    async recordRetry(phaseName) {
        this.masterProgress.retries.total++;
        if (!this.masterProgress.retries.byPhase[phaseName]) {
            this.masterProgress.retries.byPhase[phaseName] = 0;
        }
        this.masterProgress.retries.byPhase[phaseName]++;
        await this.saveMasterProgress();
    }
    async setComponentCount(count) {
        // Each component has 12 steps (see BUILD_APP_PROCESS.md)
        const componentSteps = count * 12;
        const phase = this.masterProgress.phases.component_generation;
        if (phase) {
            phase.steps = componentSteps;
        }
        this.masterProgress.totalSteps = this.calculateTotalSteps();
        await this.saveMasterProgress();
    }
    calculateTotalSteps() {
        return Object.values(this.masterProgress.phases).reduce((sum, phase) => sum + phase.steps, 0);
    }
    async startComponentGeneration(componentName, group) {
        const componentProgress = {
            component: componentName,
            group,
            status: "in_progress",
            steps: {
                spec_loaded: { status: "pending" },
                code_generated: { status: "pending" },
                file_written: { status: "pending" },
                lint_passed: { status: "pending" },
                type_check_passed: { status: "pending" },
                build_passed: { status: "pending" },
                tests_generated: { status: "pending" },
                tests_passed: { status: "pending" },
                docs_generated: { status: "pending" },
                registered: { status: "pending" },
                preview_updated: { status: "pending" },
            },
            retries: 0,
            duration: 0,
        };
        await this.saveComponentProgress(componentName, componentProgress);
        console.log(chalk_1.default.blue(`\n🔨 Generating: ${componentName}`));
    }
    async updateComponentStep(componentName, stepName, status, metadata) {
        const componentProgress = await this.loadComponentProgress(componentName);
        if (!componentProgress)
            return;
        componentProgress.steps[stepName] = {
            status,
            timestamp: new Date().toISOString(),
            metadata,
        };
        await this.saveComponentProgress(componentName, componentProgress);
        const icon = status === "completed" ? "✅" : status === "failed" ? "❌" : "⏳";
        console.log(chalk_1.default.gray(`   ${icon} ${this.formatStepName(stepName)}`));
    }
    async completeComponentGeneration(componentName, metadata) {
        const componentProgress = await this.loadComponentProgress(componentName);
        if (!componentProgress)
            return;
        componentProgress.status = "completed";
        componentProgress.metadata = metadata;
        await this.saveComponentProgress(componentName, componentProgress);
        console.log(chalk_1.default.green(`✅ Completed: ${componentName}`));
    }
    async failComponentGeneration(componentName, error, retries) {
        const componentProgress = await this.loadComponentProgress(componentName);
        if (!componentProgress)
            return;
        componentProgress.status = "failed";
        componentProgress.retries = retries;
        await this.saveComponentProgress(componentName, componentProgress);
        console.log(chalk_1.default.red(`❌ Failed: ${componentName} (${retries} retries)`));
    }
    async complete() {
        this.masterProgress.status = "completed";
        this.masterProgress.endTime = new Date().toISOString();
        this.masterProgress.percentComplete = 100;
        await this.saveMasterProgress();
        console.log(chalk_1.default.green.bold("\n🎉 Workflow Complete!\n"));
        this.displaySummary();
    }
    displaySummary() {
        const duration = Date.now() - new Date(this.masterProgress.startTime).getTime();
        const minutes = Math.floor(duration / 60000);
        const seconds = Math.floor((duration % 60000) / 1000);
        console.log(chalk_1.default.blue("📊 Workflow Summary:"));
        console.log(chalk_1.default.gray(`   Duration: ${minutes}m ${seconds}s`));
        console.log(chalk_1.default.gray(`   Total Steps: ${this.masterProgress.currentStep}/${this.masterProgress.totalSteps}`));
        console.log(chalk_1.default.gray(`   User Interactions: ${this.masterProgress.userInteractions}`));
        console.log(chalk_1.default.gray(`   Total Retries: ${this.masterProgress.retries.total}`));
        console.log();
        console.log(chalk_1.default.blue("✅ Build Checks:"));
        console.log(chalk_1.default.gray(`   TypeScript: ${this.masterProgress.buildChecks.typescript.passed} passed, ${this.masterProgress.buildChecks.typescript.failed} failed`));
        console.log(chalk_1.default.gray(`   ESLint: ${this.masterProgress.buildChecks.eslint.passed} passed, ${this.masterProgress.buildChecks.eslint.failed} failed`));
        console.log(chalk_1.default.gray(`   Build: ${this.masterProgress.buildChecks.build.passed} passed, ${this.masterProgress.buildChecks.build.failed} failed`));
        console.log(chalk_1.default.gray(`   Tests: ${this.masterProgress.buildChecks.tests.passed} passed, ${this.masterProgress.buildChecks.tests.failed} failed`));
        console.log();
    }
    async saveMasterProgress() {
        const masterFile = path_1.default.join(this.progressDir, "master.json");
        await fs.writeJson(masterFile, this.masterProgress, { spaces: 2 });
    }
    async savePhaseProgress(phaseName) {
        const phaseFile = path_1.default.join(this.progressDir, `${this.getPhaseNumber(phaseName)}-${phaseName}.json`);
        await fs.writeJson(phaseFile, this.masterProgress.phases[phaseName], {
            spaces: 2,
        });
    }
    async saveComponentProgress(componentName, progress) {
        const fileName = componentName.toLowerCase().replace(/[^a-z0-9]/g, "-");
        const componentFile = path_1.default.join(this.progressDir, "07-components", `${fileName}.json`);
        await fs.writeJson(componentFile, progress, { spaces: 2 });
    }
    async loadComponentProgress(componentName) {
        const fileName = componentName.toLowerCase().replace(/[^a-z0-9]/g, "-");
        const componentFile = path_1.default.join(this.progressDir, "07-components", `${fileName}.json`);
        try {
            return await fs.readJson(componentFile);
        }
        catch {
            return null;
        }
    }
    getPhaseNumber(phaseName) {
        const phaseNumbers = {
            preflight: "00",
            initialization: "01",
            context_generation: "02",
            types: "03",
            branding: "04",
            build_strategy: "05",
            component_list: "06",
            component_generation: "07",
            server_actions: "08",
            routes: "09",
            integration: "10",
            post_generation: "11",
        };
        return phaseNumbers[phaseName] || "99";
    }
    formatPhaseName(phaseName) {
        return phaseName
            .split("_")
            .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
            .join(" ");
    }
    formatStepName(stepName) {
        return stepName
            .split("_")
            .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
            .join(" ");
    }
    getMasterProgress() {
        return this.masterProgress;
    }
    async loadProgress() {
        const masterFile = path_1.default.join(this.progressDir, "master.json");
        try {
            return await fs.readJson(masterFile);
        }
        catch {
            return null;
        }
    }
}
exports.ProgressTracker = ProgressTracker;
//# sourceMappingURL=progressTracker.js.map