/**
 * Outbox pressure management with telemetry
 */

import { OutboxPressureConfig, TelemetryMetrics } from './types';
import { DEFAULT_CONFIG } from './constants';

export class OutboxPressureManager {
  private config: OutboxPressureConfig;
  private metrics: TelemetryMetrics;
  
  constructor(config: Partial<OutboxPressureConfig> = {}) {
    this.config = {
      maxUndelivered: config.maxUndelivered ?? DEFAULT_CONFIG.maxUndelivered,
      cleanupIntervalMs: config.cleanupIntervalMs ?? DEFAULT_CONFIG.cleanupIntervalMs,
      backpressureThreshold: config.backpressureThreshold ?? DEFAULT_CONFIG.backpressureThreshold,
      evictionPolicy: config.evictionPolicy ?? 'fifo'
    };
    
    this.metrics = {
      'starred_projects_outbox_size': 0,
      'starred_projects_outbox_backpressure_active': 0
    } as TelemetryMetrics;
  }
  
  async checkStoragePressure(undeliveredCount: number): Promise<boolean> {
    // Update metrics
    this.metrics['starred_projects_outbox_size'] = undeliveredCount;
    
    const pressureRatio = undeliveredCount / this.config.maxUndelivered;
    const backpressureActive = pressureRatio >= this.config.backpressureThreshold;
    
    // Update backpressure metric
    this.metrics['starred_projects_outbox_backpressure_active'] = backpressureActive ? 1 : 0;
    
    if (pressureRatio >= 1.0) {
      // Critical: Drop oldest notifications to make room
      const evictCount = undeliveredCount - this.config.maxUndelivered;
      await this.evictNotifications(evictCount);
      return true; // Backpressure active
    }
    
    return backpressureActive;
  }
  
  async evictNotifications(count: number): Promise<void> {
    if (count <= 0) return;
    
    // Simulate eviction based on policy
    switch (this.config.evictionPolicy) {
      case 'fifo':
        await this.evictFIFO(count);
        break;
      case 'lifo':
        await this.evictLIFO(count);
        break;
      case 'priority':
        await this.evictByPriority(count);
        break;
    }
  }
  
  private async evictFIFO(_count: number): Promise<void> {
    // Simulate: DELETE FROM notification_outbox 
    // WHERE delivered_at IS NULL 
    // ORDER BY created_at ASC 
    // LIMIT count
    // Evicting oldest notifications (FIFO policy)
  }
  
  private async evictLIFO(_count: number): Promise<void> {
    // Simulate: DELETE FROM notification_outbox 
    // WHERE delivered_at IS NULL 
    // ORDER BY created_at DESC 
    // LIMIT count
    // Evicting newest notifications (LIFO policy)
  }
  
  private async evictByPriority(_count: number): Promise<void> {
    // Simulate: DELETE FROM notification_outbox 
    // WHERE delivered_at IS NULL 
    // ORDER BY priority ASC, created_at ASC 
    // LIMIT count
    // Evicting lowest priority notifications
  }
  
  async cleanupDeliveredNotifications(): Promise<void> {
    // Simulate: DELETE FROM notification_outbox 
    // WHERE delivered_at IS NOT NULL 
    // AND delivered_at < datetime('now', '-${cleanupIntervalMs / 1000} seconds')
    // Cleaning up delivered notifications older than cleanup interval
  }
  
  getMetrics(): TelemetryMetrics {
    return { ...this.metrics };
  }
  
  getConfig(): OutboxPressureConfig {
    return { ...this.config };
  }
}

/**
 * Create default outbox pressure manager
 */
export function createDefaultOutboxPressureManager(): OutboxPressureManager {
  return new OutboxPressureManager();
}

/**
 * Create outbox pressure manager with custom config
 */
export function createOutboxPressureManager(config: Partial<OutboxPressureConfig>): OutboxPressureManager {
  return new OutboxPressureManager(config);
}

/**
 * Outbox pressure configuration presets
 */
export const OUTBOX_PRESSURE_PRESETS = {
  // Conservative: Low memory usage, frequent cleanup
  conservative: {
    maxUndelivered: 500,
    backpressureThreshold: 0.7,
    cleanupIntervalMs: 1800000, // 30 minutes
    evictionPolicy: 'fifo' as const
  },
  
  // Balanced: Good performance, reasonable memory usage
  balanced: {
    maxUndelivered: 1000,
    backpressureThreshold: 0.8,
    cleanupIntervalMs: 3600000, // 1 hour
    evictionPolicy: 'fifo' as const
  },
  
  // Aggressive: High throughput, more memory usage
  aggressive: {
    maxUndelivered: 2000,
    backpressureThreshold: 0.9,
    cleanupIntervalMs: 7200000, // 2 hours
    evictionPolicy: 'priority' as const
  }
} as const;
