import type { Histogram, Counter, Meter, Span, Tracer, Telemetry } from '../domain/telemetry.js';

class NoopSpan implements Span {
  end(): void {}
  setError(_err: unknown): void {}
}

export class NoopTracer implements Tracer {
  startSpan(_name: string): Span {
    return new NoopSpan();
  }
  async trace<T>(name: string, fn: () => Promise<T>): Promise<T> {
    return fn();
  }
}

class NoopCounter implements Counter {
  add(_value: number, _attributes?: Record<string, string>): void {}
}

class NoopHistogram implements Histogram {
  record(_value: number, _attributes?: Record<string, string>): void {}
}

class NoopMeter implements Meter {
  counter(_name: string): Counter {
    return new NoopCounter();
  }
  histogram(_name: string): Histogram {
    return new NoopHistogram();
  }
}

export class InMemoryMeter implements Meter {
  readonly data = new Map<string, number>();
  counter(name: string): Counter {
    return {
      add: (value, _attributes) => {
        this.data.set(name, (this.data.get(name) ?? 0) + value);
      },
    };
  }
  histogram(_name: string): Histogram {
    return { record: () => undefined };
  }
  snapshot(): Record<string, number> {
    return Object.fromEntries(this.data);
  }
}

export function createNoOpTelemetry(): Telemetry {
  return { tracer: new NoopTracer(), meter: new NoopMeter() };
}

export function createInMemoryTelemetry(): { telemetry: Telemetry; meter: InMemoryMeter } {
  const meter = new InMemoryMeter();
  return { telemetry: { tracer: new NoopTracer(), meter }, meter };
}
