"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Telemetry = exports.TelemetryEventSchema = void 0;
const crypto_1 = require("crypto");
const posthog_node_1 = require("posthog-node");
const zod_1 = require("zod");
const constants_1 = require("./constants");
const envars_1 = require("./envars");
const fetch_1 = require("./fetch");
const generated_constants_1 = require("./generated-constants");
const accounts_1 = require("./globalConfig/accounts");
const logger_1 = __importDefault(require("./logger"));
exports.TelemetryEventSchema = zod_1.z.object({
    event: zod_1.z.enum([
        'assertion_used',
        'command_used',
        'eval_ran',
        'feature_used',
        'funnel',
        'webui_action',
        'webui_api',
        'webui_page_view',
    ]),
    packageVersion: zod_1.z.string().optional().default(constants_1.VERSION),
    properties: zod_1.z.record(zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean(), zod_1.z.array(zod_1.z.string())])),
});
const CONSENT_ENDPOINT = 'https://api.promptfoo.dev/consent';
const EVENTS_ENDPOINT = 'https://a.promptfoo.app';
const KA_ENDPOINT = 'https://ka.promptfoo.app/';
let posthogClient = null;
function getPostHogClient() {
    if ((0, envars_1.getEnvBool)('PROMPTFOO_DISABLE_TELEMETRY') || (0, envars_1.getEnvBool)('IS_TESTING')) {
        return null;
    }
    if (posthogClient === null && generated_constants_1.POSTHOG_KEY) {
        try {
            posthogClient = new posthog_node_1.PostHog(generated_constants_1.POSTHOG_KEY, {
                host: EVENTS_ENDPOINT,
            });
        }
        catch {
            posthogClient = null;
        }
    }
    return posthogClient;
}
const TELEMETRY_TIMEOUT_MS = 1000;
class Telemetry {
    constructor() {
        this.telemetryDisabledRecorded = false;
        this.id = (0, accounts_1.getUserId)();
        this.email = (0, accounts_1.getUserEmail)();
        this.identify();
    }
    identify() {
        if (this.disabled || (0, envars_1.getEnvBool)('IS_TESTING')) {
            return;
        }
        const client = getPostHogClient();
        if (client) {
            try {
                client.identify({
                    distinctId: this.id,
                    properties: {
                        email: this.email,
                        isLoggedIntoCloud: (0, accounts_1.isLoggedIntoCloud)(),
                    },
                });
                client.flush().catch(() => {
                    // Silently ignore flush errors
                });
            }
            catch (error) {
                logger_1.default.debug(`PostHog identify error: ${error}`);
            }
        }
        (0, fetch_1.fetchWithTimeout)(KA_ENDPOINT, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ profile_id: this.id, email: this.email }),
        }, TELEMETRY_TIMEOUT_MS).catch(() => {
            // pass
        });
    }
    get disabled() {
        return (0, envars_1.getEnvBool)('PROMPTFOO_DISABLE_TELEMETRY');
    }
    recordTelemetryDisabled() {
        if (!this.telemetryDisabledRecorded) {
            this.sendEvent('feature_used', { feature: 'telemetry disabled' });
            this.telemetryDisabledRecorded = true;
        }
    }
    record(eventName, properties) {
        if (this.disabled) {
            this.recordTelemetryDisabled();
        }
        else {
            this.sendEvent(eventName, properties);
        }
    }
    sendEvent(eventName, properties) {
        const propertiesWithMetadata = {
            ...properties,
            packageVersion: constants_1.VERSION,
            isRunningInCi: (0, envars_1.isCI)(),
        };
        const client = getPostHogClient();
        if (client && !(0, envars_1.getEnvBool)('IS_TESTING')) {
            try {
                client.capture({
                    distinctId: this.id,
                    event: eventName,
                    properties: propertiesWithMetadata,
                });
                client.flush().catch(() => {
                    // Silently ignore flush errors
                });
            }
            catch (error) {
                logger_1.default.debug(`PostHog capture error: ${error}`);
            }
        }
        const kaBody = {
            profile_id: this.id,
            email: this.email,
            events: [
                {
                    message_id: (0, crypto_1.randomUUID)(),
                    type: 'track',
                    event: eventName,
                    properties: propertiesWithMetadata,
                    sent_at: new Date().toISOString(),
                },
            ],
        };
        fetch(KA_ENDPOINT, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'User-Agent': `promptfoo/${constants_1.VERSION}`,
            },
            body: JSON.stringify(kaBody),
        }).catch(() => {
            // pass
        });
    }
    /**
     * This is a separate endpoint to save consent used only for redteam data synthesis for "harmful" plugins.
     */
    async saveConsent(email, metadata) {
        try {
            const response = await (0, fetch_1.fetchWithTimeout)(CONSENT_ENDPOINT, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ email, metadata }),
            }, TELEMETRY_TIMEOUT_MS);
            if (!response.ok) {
                throw new Error(`Failed to save consent: ${response.statusText}`);
            }
        }
        catch (err) {
            logger_1.default.debug(`Failed to save consent: ${err.message}`);
        }
    }
}
exports.Telemetry = Telemetry;
const telemetry = new Telemetry();
exports.default = telemetry;
//# sourceMappingURL=telemetry.js.map