// Local type alias matching the contract in @repo/core-shared/instrumentation.
// Kept inline to avoid a build-graph cycle between core-testing and core-shared.
type MetricAttributeValue = string | number | boolean;

interface IMetrics {
  counter(
    name: string,
    value?: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;
  histogram(
    name: string,
    value: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;
  gauge(
    name: string,
    value: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;
}

export type RecordedMetric = {
  kind: "counter" | "histogram" | "gauge";
  name: string;
  value: number;
  attributes: Record<string, MetricAttributeValue>;
};

export class RecordingMetrics implements IMetrics {
  metrics: RecordedMetric[] = [];

  counter(
    name: string,
    value = 1,
    attributes: Record<string, MetricAttributeValue> = {},
  ): void {
    this.metrics.push({ kind: "counter", name, value, attributes });
  }

  histogram(
    name: string,
    value: number,
    attributes: Record<string, MetricAttributeValue> = {},
  ): void {
    this.metrics.push({ kind: "histogram", name, value, attributes });
  }

  gauge(
    name: string,
    value: number,
    attributes: Record<string, MetricAttributeValue> = {},
  ): void {
    this.metrics.push({ kind: "gauge", name, value, attributes });
  }

  reset(): void {
    this.metrics = [];
  }

  find(
    predicate: (m: RecordedMetric) => boolean,
  ): RecordedMetric | undefined {
    return this.metrics.find(predicate);
  }
}
