// Tracing Middleware
// Adds distributed tracing to Express requests

import { Request, Response, NextFunction } from 'express';
import { tracingService } from './tracing.service';

export interface TracedRequest extends Request {
  traceContext?: {
    traceId: string;
    spanId: string;
    parentSpanId?: string;
  };
}

/**
 * Tracing middleware
 * Creates a span for each HTTP request
 */
export function tracingMiddleware(req: TracedRequest, res: Response, next: NextFunction): void {
  // Extract trace context from headers
  const parentContext = tracingService.extractTraceContext(req.headers);

  // Start new span for this request
  const context = tracingService.startSpan(
    `${req.method} ${req.path}`,
    parentContext?.traceId,
    parentContext?.spanId,
    {
      'http.method': req.method,
      'http.path': req.path,
      'http.url': req.url,
      'http.user_agent': req.get('user-agent'),
      'http.remote_ip': req.ip,
    }
  );

  req.traceContext = context;

  // Inject trace context into response headers
  const traceHeaders = tracingService.injectTraceContext(context);
  Object.entries(traceHeaders).forEach(([key, value]) => {
    res.setHeader(key, value);
  });

  // End span when response finishes
  res.on('finish', () => {
    const status = res.statusCode >= 400 ? 'error' : 'ok';
    tracingService.endSpan(context.traceId, context.spanId, status);
  });

  next();
}
