/**
 * Global telemetry manager
 * This module provides the main public API for telemetry and delegates to specialized modules
 */
// Import internal dependencies
import { isTelemetryEnabled, setVersion, telemetryDebug, } from './telemetry-utils.js';
/**
 * TelemetryManager - Singleton class for managing CLI telemetry
 */
class TelemetryManager {
    backboardOtelClient;
    sentryClient;
    /**
     * Create telemetry object for command_not_found errors
     */
    reportCmdNotFound(config) {
        return {
            _type: 'otel',
            cliRunDuration: 0,
            command: 'invalid_command',
            commandRunDuration: 0,
            exitCode: 0,
            exitState: 'command_not_found',
            isTTY: process.stdin.isTTY,
            isVersionOrHelp: false,
            lifecycleHookCompletion: {
                command_not_found: true,
                init: true,
                postrun: false,
                prerun: false,
            },
            os: config.platform,
            version: config.version,
        };
    }
    /**
     * Main orchestrator: Send telemetry data to appropriate destinations
     * - Errors go to both Honeycomb and Sentry
     * - Regular telemetry goes to Honeycomb only
     */
    async sendTelemetry(currentTelemetry) {
        if (!isTelemetryEnabled()) {
            telemetryDebug('Telemetry disabled, skipping send');
            return;
        }
        const { backboardOtelClient, sentryClient } = await this.getClients();
        const telemetry = currentTelemetry;
        if (telemetry instanceof Error) {
            // Filter SIGINT errors from Sentry (user Ctrl+C is not an error to report)
            // But still send to Honeycomb for analytics
            const isSIGINT = telemetry.message === 'Received SIGINT';
            if (isSIGINT) {
                telemetryDebug('Sending error to Honeycomb: %s', telemetry.message);
                await backboardOtelClient.send(telemetry);
            }
            else {
                telemetryDebug('Sending error to Honeycomb and Sentry: %s', telemetry.message);
                await Promise.all([
                    backboardOtelClient.send(telemetry),
                    sentryClient.send(telemetry),
                ]);
            }
        }
        else {
            telemetryDebug('Sending telemetry for command: %s', telemetry.command);
            await backboardOtelClient.send(telemetry);
        }
    }
    /**
     * Create telemetry object for regular commands or version/help
     */
    setupTelemetry(config, opts) {
        // Store version from config (eliminates need to read package.json)
        setVersion(config.version);
        const now = new Date();
        const cmdStartTime = now.getTime();
        const isRegularCmd = Boolean(opts.Command);
        const mcpMode = process.env.HEROKU_MCP_MODE === 'true';
        const mcpServerVersion = process.env.HEROKU_MCP_SERVER_VERSION || 'unknown';
        const irregularTelemetryObject = {
            _type: 'otel',
            cliRunDuration: 0,
            command: opts.id || 'unknown',
            commandRunDuration: cmdStartTime,
            exitCode: 0,
            exitState: 'successful',
            isTTY: process.stdin.isTTY,
            isVersionOrHelp: true,
            lifecycleHookCompletion: {
                command_not_found: false,
                init: true,
                postrun: false,
                prerun: false,
            },
            os: config.platform,
            version: `${config.version}${mcpMode ? ` (MCP ${mcpServerVersion})` : ''}`,
        };
        if (isRegularCmd && opts.Command) {
            return {
                ...irregularTelemetryObject,
                command: opts.Command.id,
                isVersionOrHelp: false,
                lifecycleHookCompletion: {
                    ...irregularTelemetryObject.lifecycleHookCompletion,
                    prerun: true,
                },
            };
        }
        return irregularTelemetryObject;
    }
    /**
     * Lazy load telemetry clients to avoid loading heavy OpenTelemetry/Sentry
     * libraries during CLI initialization
     */
    async getClients() {
        if (!this.backboardOtelClient || !this.sentryClient) {
            const [{ default: BackboardOtelClient }, { default: SentryClient }] = await Promise.all([
                import('./backboard-otel-client.js'),
                import('./sentry-client.js'),
            ]);
            this.backboardOtelClient = new BackboardOtelClient();
            this.sentryClient = new SentryClient();
            telemetryDebug('Lazy-loaded telemetry clients');
        }
        // TypeScript: Both clients are guaranteed to be defined after the above check
        return {
            backboardOtelClient: this.backboardOtelClient,
            sentryClient: this.sentryClient,
        };
    }
}
// Export singleton instance
export const telemetryManager = new TelemetryManager();
