"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AutoBeTokenUsage = void 0;
const AutoBeTokenUsageComponent_1 = require("./AutoBeTokenUsageComponent");
/**
 * Comprehensive token usage tracker for the AutoBe vibe coding system.
 *
 * This class provides centralized tracking and management of token consumption
 * across all AI agents in the automated development pipeline. It captures
 * detailed token usage statistics for each processing phase - from initial
 * requirements analysis through final implementation - enabling cost
 * monitoring, performance optimization, and resource utilization analysis.
 *
 * The token usage data includes both input tokens (with cache efficiency) and
 * output tokens (with generation type breakdowns), providing insights into AI
 * processing efficiency and helping optimize the balance between computational
 * costs and output quality.
 *
 * @author SunRabbit123
 */
class AutoBeTokenUsage {
    /**
     * Aggregated token usage statistics across all agents.
     *
     * Provides a unified view of token consumption by combining data from all
     * processing phases in the vibe coding pipeline. This computed property
     * dynamically calculates the sum of all agent components (facade, analyze,
     * prisma, interface, test, realize) whenever accessed, ensuring the aggregate
     * always reflects the current state of token usage.
     *
     * The aggregation performs element-wise addition across all token metrics,
     * including total counts, input breakdowns with cache statistics, and output
     * categorizations by generation type. This comprehensive view enables overall
     * cost assessment and resource utilization analysis for the entire automated
     * development session.
     */
    get aggregate() {
        return AutoBeTokenUsage.keys()
            .reduce((acc, cur) => AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(acc, this[cur]), new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent())
            .toJSON();
    }
    constructor(props) {
        if (props === undefined) {
            this.facade = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            this.analyze = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            this.prisma = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            this.interface = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            this.test = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            this.realize = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent();
            return;
        }
        else if (props instanceof AutoBeTokenUsage) {
            this.facade = props.facade;
            this.analyze = props.analyze;
            this.prisma = props.prisma;
            this.interface = props.interface;
            this.test = props.test;
            this.realize = props.realize;
        }
        else {
            this.facade = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.facade);
            this.analyze = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.analyze);
            this.prisma = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.prisma);
            this.interface = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.interface);
            this.test = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.test);
            this.realize = new AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent(props.realize);
        }
    }
    assign(props) {
        this.facade.assign(props.facade);
        this.analyze.assign(props.analyze);
        this.prisma.assign(props.prisma);
        this.interface.assign(props.interface);
        this.test.assign(props.test);
        this.realize.assign(props.realize);
    }
    /**
     * Serialize token usage data to JSON format.
     *
     * Converts the internal token usage representation to the standardized
     * IAutoBeTokenUsageJson format, suitable for persistence, transmission, or
     * external analysis. The serialized data maintains the complete structure
     * including all agent phases and detailed token breakdowns.
     *
     * @returns JSON representation of token usage statistics
     */
    toJSON() {
        return {
            aggregate: this.aggregate,
            facade: this.facade.toJSON(),
            analyze: this.analyze.toJSON(),
            prisma: this.prisma.toJSON(),
            interface: this.interface.toJSON(),
            test: this.test.toJSON(),
            realize: this.realize.toJSON(),
        };
    }
    /* -----------------------------------------------------------
      OPERATORS
    ----------------------------------------------------------- */
    /**
     * Record token usage for specific processing stages.
     *
     * Updates token consumption statistics for one or more agent phases based on
     * the provided usage data. This method allows selective recording of token
     * usage for specific stages, enabling fine-grained tracking during
     * multi-phase processing or when certain agents are invoked multiple times.
     *
     * @example
     *   ```ts
     *   tokenUsage.record(
     *     { total: 150, input: { total: 100, cached: 20 }, output: { total: 50, ... } },
     *     ['analyze', 'prisma']
     *   );
     *   ```;
     *
     * @param usage - Token usage component data to record
     * @param additionalStages - Array of stage names to update with the usage
     *   data
     */
    record(usage, additionalStages = []) {
        additionalStages.forEach((stage) => {
            this[stage].increment(usage);
        });
    }
    /**
     * Increment current token usage with data from another instance.
     *
     * Adds token usage statistics from another AutoBeTokenUsage instance to this
     * one, updating all agent phases simultaneously. This method is useful for
     * combining token usage from parallel processing, multiple runs, or when
     * aggregating statistics from distributed agent executions.
     *
     * @param usage - AutoBeTokenUsage instance to add to current statistics
     * @returns This instance for method chaining
     */
    increment(usage) {
        AutoBeTokenUsage.keys().forEach((key) => {
            this[key].increment(usage[key]);
        });
        return this;
    }
    /** @internal */
    decrement(usage) {
        AutoBeTokenUsage.keys().forEach((key) => {
            this[key].decrement(usage[key]);
        });
        return this;
    }
    /**
     * Create a new instance combining token usage from two sources.
     *
     * Performs element-wise addition of token usage statistics from two
     * AutoBeTokenUsage instances, creating a new instance with the combined
     * totals. This static method is useful for aggregating token usage across
     * multiple vibe coding sessions or when merging statistics from different
     * execution contexts.
     *
     * @param usageA - First token usage instance
     * @param usageB - Second token usage instance
     * @returns New instance with combined token usage statistics
     */
    static plus(usageA, usageB) {
        return new AutoBeTokenUsage({
            facade: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.facade, usageB.facade),
            analyze: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.analyze, usageB.analyze),
            prisma: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.prisma, usageB.prisma),
            interface: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.interface, usageB.interface),
            test: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.test, usageB.test),
            realize: AutoBeTokenUsageComponent_1.AutoBeTokenUsageComponent.plus(usageA.realize, usageB.realize),
        });
    }
    /**
     * Get all agent phase keys for iteration.
     *
     * Returns a readonly array of all agent phase names used in the vibe coding
     * system. This internal utility method ensures consistent iteration over all
     * token usage components when performing operations like aggregation or
     * serialization.
     *
     * @returns Readonly array of agent phase keys
     * @internal
     */
    static keys() {
        return [
            "facade",
            "analyze",
            "prisma",
            "interface",
            "test",
            "realize",
        ];
    }
}
exports.AutoBeTokenUsage = AutoBeTokenUsage;
//# sourceMappingURL=AutoBeTokenUsage.js.map