// OpenTelemetry Node SDK bootstrap for FarmaClic backend.
// Started as a side-effect import from server.js (ESM).
//
// Env vars (set by docker-compose):
//   OTEL_SERVICE_NAME        — default: farmaclic-backend
//   OTEL_EXPORTER_OTLP_ENDPOINT — OTLP gRPC endpoint (e.g. http://alloy:4317)
//
// Exports traces to the shared Grafana Alloy collector, where they are
// routed to Tempo.

import { NodeSDK } from '@opentelemetry/sdk-node';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import * as resources from '@opentelemetry/resources';
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';

const serviceName = process.env.OTEL_SERVICE_NAME || 'farmaclic-backend';
const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4317';

// Use plain string attribute keys (not the semantic-conventions named exports)
// so we don't depend on a specific @opentelemetry/semantic-conventions version.
const resource = typeof resources.resourceFromAttributes === 'function'
  ? resources.resourceFromAttributes({
      'service.name': serviceName,
      'service.namespace': 'farmaclic',
    })
  : new resources.Resource({
      'service.name': serviceName,
      'service.namespace': 'farmaclic',
    });

// Metrics → OTLP → Alloy → Prometheus remote_write. The PeriodicExportingMetricReader
// makes the auto-instrumentations (http/express/redis) emit request duration/error
// metrics with no extra code, on top of the custom business metrics in src/metrics.js.
const metricReader = new PeriodicExportingMetricReader({
  exportIntervalMillis: 15_000,
  exporter: new OTLPMetricExporter({ url: otlpEndpoint }),
});

const sdk = new NodeSDK({
  resource,
  traceExporter: new OTLPTraceExporter({ url: otlpEndpoint }),
  metricReader,
  instrumentations: [
    getNodeAutoInstrumentations({
      // Disable fs by default — it is noisy and rarely useful.
      '@opentelemetry/instrumentation-fs': { enabled: false },
      '@opentelemetry/instrumentation-dns': { enabled: false },
    }),
    new PinoInstrumentation(),
  ],
});

if (process.env.NODE_ENV !== 'test') {
  sdk.start();
}

const shutdown = async () => {
  try {
    if (process.env.NODE_ENV !== 'test') {
      await sdk.shutdown();
    }
  } catch (err) {
    // eslint-disable-next-line no-console
    console.error('OpenTelemetry shutdown failed', err);
  }
};

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