/**
 * Metrics tracking for the LLM filter pipeline.
 *
 * Records token savings, cache efficiency, and filter latency to enable
 * observability of the smart context optimization layer.
 */

export interface FilterMetricsSnapshot {
  /** Total estimated tokens that entered the filter pipeline */
  totalTokensProcessed: number;
  /** Estimated tokens saved by filtering */
  tokensSaved: number;
  /** Number of cache hits (filter decision reused) */
  cacheHits: number;
  /** Number of cache misses (required fresh decision) */
  cacheMisses: number;
  /** Number of filter operations performed */
  filterCount: number;
  /** Average filter latency in milliseconds (0 if no operations) */
  averageFilterLatencyMs: number;
}

/**
 * Accumulates metrics for the LLM filter pipeline.
 *
 * Thread-safe for single-threaded Node.js usage. Call `getStats()` to
 * retrieve a snapshot of current metrics.
 */
export class FilterMetrics {
  private totalTokensProcessed = 0;
  private tokensSaved = 0;
  private cacheHits = 0;
  private cacheMisses = 0;
  private filterCount = 0;
  private totalFilterLatencyMs = 0;

  /**
   * Record a single filter operation.
   *
   * @param originalTokens - Estimated tokens before filtering.
   * @param filteredTokens - Estimated tokens after filtering.
   * @param latencyMs - Time taken for the filter operation in ms.
   */
  recordFilter(originalTokens: number, filteredTokens: number, latencyMs: number): void {
    this.totalTokensProcessed += originalTokens;
    this.tokensSaved += Math.max(0, originalTokens - filteredTokens);
    this.filterCount++;
    this.totalFilterLatencyMs += latencyMs;
  }

  /** Record a cache hit. */
  recordCacheHit(): void {
    this.cacheHits++;
  }

  /** Record a cache miss. */
  recordCacheMiss(): void {
    this.cacheMisses++;
  }

  /** Return a snapshot of all accumulated metrics. */
  getStats(): FilterMetricsSnapshot {
    return {
      totalTokensProcessed: this.totalTokensProcessed,
      tokensSaved: this.tokensSaved,
      cacheHits: this.cacheHits,
      cacheMisses: this.cacheMisses,
      filterCount: this.filterCount,
      averageFilterLatencyMs:
        this.filterCount > 0 ? this.totalFilterLatencyMs / this.filterCount : 0,
    };
  }

  /** Reset all metrics to zero. */
  reset(): void {
    this.totalTokensProcessed = 0;
    this.tokensSaved = 0;
    this.cacheHits = 0;
    this.cacheMisses = 0;
    this.filterCount = 0;
    this.totalFilterLatencyMs = 0;
  }
}
