import type { MetricsProtocol } from "../di/bind-protocols";

export type MetricAttributeValue = string | number | boolean;

/**
 * Vendor-neutral metrics signal interface. Mirrors the pattern of ITracer / ILogger.
 * Three impls: NoopMetrics (noop), OtelMetrics (OTel API), RecordingMetrics (core-testing).
 *
 * Extends MetricsProtocol from `core-shared/di/bind-protocols` so the type
 * system enforces structural compatibility — narrowing IMetrics below the
 * protocol surface causes a typecheck error.
 *
 * gauge() limitation: uses UpDownCounter under the hood, which accumulates deltas.
 * True "set to absolute value" semantics require ObservableGauge with a callback —
 * deferred to a v2 interface when the first true-gauge use case lands.
 */
export interface IMetrics extends MetricsProtocol {
  /** Monotonic counter. Use for event counts (signups, errors, requests). */
  counter(
    name: string,
    value?: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;

  /** Distribution. Use for measured quantities (latency, payload size). */
  histogram(
    name: string,
    value: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;

  /**
   * Point-in-time value. UpDownCounter under the hood — true gauge semantics
   * (set to absolute value) require ObservableGauge with an async callback;
   * that is deferred to a future v2 spec when the first true-gauge use case arrives.
   */
  gauge(
    name: string,
    value: number,
    attributes?: Record<string, MetricAttributeValue>,
  ): void;
}
