/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { initializeTelemetry, shutdownTelemetry } from './sdk.js';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-grpc';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import { OTLPTraceExporter as OTLPTraceExporterHttp } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPLogExporter as OTLPLogExporterHttp } from '@opentelemetry/exporter-logs-otlp-http';
import { OTLPMetricExporter as OTLPMetricExporterHttp } from '@opentelemetry/exporter-metrics-otlp-http';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { GcpTraceExporter, GcpLogExporter, GcpMetricExporter, } from './gcp-exporters.js';
import { TelemetryTarget } from './index.js';
import * as os from 'node:os';
import * as path from 'node:path';
vi.mock('@opentelemetry/exporter-trace-otlp-grpc');
vi.mock('@opentelemetry/exporter-logs-otlp-grpc');
vi.mock('@opentelemetry/exporter-metrics-otlp-grpc');
vi.mock('@opentelemetry/exporter-trace-otlp-http');
vi.mock('@opentelemetry/exporter-logs-otlp-http');
vi.mock('@opentelemetry/exporter-metrics-otlp-http');
vi.mock('@opentelemetry/sdk-node');
vi.mock('./gcp-exporters.js');
describe('Telemetry SDK', () => {
    let mockConfig;
    beforeEach(() => {
        vi.clearAllMocks();
        mockConfig = {
            getTelemetryEnabled: () => true,
            getTelemetryOtlpEndpoint: () => 'http://localhost:4317',
            getTelemetryOtlpProtocol: () => 'grpc',
            getTelemetryTarget: () => 'local',
            getTelemetryUseCollector: () => false,
            getTelemetryOutfile: () => undefined,
            getDebugMode: () => false,
            getSessionId: () => 'test-session',
        };
    });
    afterEach(async () => {
        await shutdownTelemetry(mockConfig);
    });
    it('should use gRPC exporters when protocol is grpc', () => {
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
        expect(OTLPLogExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
        expect(OTLPMetricExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
        expect(NodeSDK.prototype.start).toHaveBeenCalled();
    });
    it('should use HTTP exporters when protocol is http', () => {
        vi.spyOn(mockConfig, 'getTelemetryEnabled').mockReturnValue(true);
        vi.spyOn(mockConfig, 'getTelemetryOtlpProtocol').mockReturnValue('http');
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('http://localhost:4318');
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporterHttp).toHaveBeenCalledWith({
            url: 'http://localhost:4318/',
        });
        expect(OTLPLogExporterHttp).toHaveBeenCalledWith({
            url: 'http://localhost:4318/',
        });
        expect(OTLPMetricExporterHttp).toHaveBeenCalledWith({
            url: 'http://localhost:4318/',
        });
        expect(NodeSDK.prototype.start).toHaveBeenCalled();
    });
    it('should parse gRPC endpoint correctly', () => {
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('https://my-collector.com');
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporter).toHaveBeenCalledWith(expect.objectContaining({ url: 'https://my-collector.com' }));
    });
    it('should parse HTTP endpoint correctly', () => {
        vi.spyOn(mockConfig, 'getTelemetryOtlpProtocol').mockReturnValue('http');
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('https://my-collector.com');
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporterHttp).toHaveBeenCalledWith(expect.objectContaining({ url: 'https://my-collector.com/' }));
    });
    it('should use direct GCP exporters when target is gcp, project ID is set, and useCollector is false', () => {
        vi.spyOn(mockConfig, 'getTelemetryTarget').mockReturnValue(TelemetryTarget.GCP);
        vi.spyOn(mockConfig, 'getTelemetryUseCollector').mockReturnValue(false);
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('');
        const originalEnv = process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
        process.env['OTLP_GOOGLE_CLOUD_PROJECT'] = 'test-project';
        try {
            initializeTelemetry(mockConfig);
            expect(GcpTraceExporter).toHaveBeenCalledWith('test-project');
            expect(GcpLogExporter).toHaveBeenCalledWith('test-project');
            expect(GcpMetricExporter).toHaveBeenCalledWith('test-project');
            expect(NodeSDK.prototype.start).toHaveBeenCalled();
        }
        finally {
            if (originalEnv) {
                process.env['OTLP_GOOGLE_CLOUD_PROJECT'] = originalEnv;
            }
            else {
                delete process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
            }
        }
    });
    it('should use OTLP exporters when target is gcp but useCollector is true', () => {
        vi.spyOn(mockConfig, 'getTelemetryTarget').mockReturnValue(TelemetryTarget.GCP);
        vi.spyOn(mockConfig, 'getTelemetryUseCollector').mockReturnValue(true);
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
        expect(OTLPLogExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
        expect(OTLPMetricExporter).toHaveBeenCalledWith({
            url: 'http://localhost:4317',
            compression: 'gzip',
        });
    });
    it('should not use GCP exporters when project ID environment variable is not set', () => {
        vi.spyOn(mockConfig, 'getTelemetryTarget').mockReturnValue(TelemetryTarget.GCP);
        vi.spyOn(mockConfig, 'getTelemetryUseCollector').mockReturnValue(false);
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('');
        const originalOtlpEnv = process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
        const originalGoogleEnv = process.env['GOOGLE_CLOUD_PROJECT'];
        delete process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
        delete process.env['GOOGLE_CLOUD_PROJECT'];
        try {
            initializeTelemetry(mockConfig);
            expect(GcpTraceExporter).not.toHaveBeenCalled();
            expect(GcpLogExporter).not.toHaveBeenCalled();
            expect(GcpMetricExporter).not.toHaveBeenCalled();
            expect(NodeSDK.prototype.start).toHaveBeenCalled();
        }
        finally {
            if (originalOtlpEnv) {
                process.env['OTLP_GOOGLE_CLOUD_PROJECT'] = originalOtlpEnv;
            }
            if (originalGoogleEnv) {
                process.env['GOOGLE_CLOUD_PROJECT'] = originalGoogleEnv;
            }
        }
    });
    it('should use GOOGLE_CLOUD_PROJECT as fallback when OTLP_GOOGLE_CLOUD_PROJECT is not set', () => {
        vi.spyOn(mockConfig, 'getTelemetryTarget').mockReturnValue(TelemetryTarget.GCP);
        vi.spyOn(mockConfig, 'getTelemetryUseCollector').mockReturnValue(false);
        vi.spyOn(mockConfig, 'getTelemetryOtlpEndpoint').mockReturnValue('');
        const originalOtlpEnv = process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
        const originalGoogleEnv = process.env['GOOGLE_CLOUD_PROJECT'];
        delete process.env['OTLP_GOOGLE_CLOUD_PROJECT'];
        process.env['GOOGLE_CLOUD_PROJECT'] = 'fallback-project';
        try {
            initializeTelemetry(mockConfig);
            expect(GcpTraceExporter).toHaveBeenCalledWith('fallback-project');
            expect(GcpLogExporter).toHaveBeenCalledWith('fallback-project');
            expect(GcpMetricExporter).toHaveBeenCalledWith('fallback-project');
            expect(NodeSDK.prototype.start).toHaveBeenCalled();
        }
        finally {
            if (originalOtlpEnv) {
                process.env['OTLP_GOOGLE_CLOUD_PROJECT'] = originalOtlpEnv;
            }
            if (originalGoogleEnv) {
                process.env['GOOGLE_CLOUD_PROJECT'] = originalGoogleEnv;
            }
            else {
                delete process.env['GOOGLE_CLOUD_PROJECT'];
            }
        }
    });
    it('should not use OTLP exporters when telemetryOutfile is set', () => {
        vi.spyOn(mockConfig, 'getTelemetryOutfile').mockReturnValue(path.join(os.tmpdir(), 'test.log'));
        initializeTelemetry(mockConfig);
        expect(OTLPTraceExporter).not.toHaveBeenCalled();
        expect(OTLPLogExporter).not.toHaveBeenCalled();
        expect(OTLPMetricExporter).not.toHaveBeenCalled();
        expect(OTLPTraceExporterHttp).not.toHaveBeenCalled();
        expect(OTLPLogExporterHttp).not.toHaveBeenCalled();
        expect(OTLPMetricExporterHttp).not.toHaveBeenCalled();
        expect(NodeSDK.prototype.start).toHaveBeenCalled();
    });
});
//# sourceMappingURL=sdk.test.js.map