import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
import { createAddHookMessageChannel } from "import-in-the-middle";
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { settings } from "@pkg/settings";
import { register } from "node:module";

const { registerOptions } = createAddHookMessageChannel();
register("import-in-the-middle/hook.mjs", import.meta.url, registerOptions);

const normalizedEndpoint = settings.otelExporterOtlpHttpEndpoint.startsWith(
    "http",
)
    ? settings.otelExporterOtlpHttpEndpoint
    : `http://${settings.otelExporterOtlpHttpEndpoint}`;

if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
    process.env.OTEL_EXPORTER_OTLP_ENDPOINT = normalizedEndpoint;
}

const sdk = new NodeSDK({
    serviceName: `${settings.otelServiceName}-processor`,
    traceExporter: new OTLPTraceExporter(),
    metricReader: new PeriodicExportingMetricReader({
        exporter: new OTLPMetricExporter(),
        exportIntervalMillis: 10_000,
    }),
    logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter())],
    instrumentations: [
        getNodeAutoInstrumentations({
            "@opentelemetry/instrumentation-winston": {
                // We add OpenTelemetryTransportV3 explicitly in @pkg/logger.
                disableLogSending: true,
            },
        }),
    ],
});

sdk.start();

const shutdown = () => {
    void sdk.shutdown();
};

process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
