/**
 * Metrics Repository
 * Handles CRUD operations for metrics and logs tables
 */

import { BaseRepository } from '../base.repository.ts';
import type { IMetric, ILogEntry } from '../../types.ts';

export class MetricsRepository extends BaseRepository {
  // ============ Metrics ============

  addMetric(metric: Omit<IMetric, 'id'>): void {
    this.query(
      `INSERT INTO metrics (service_id, timestamp, cpu_percent, memory_used, memory_limit, network_rx_bytes, network_tx_bytes)
       VALUES (?, ?, ?, ?, ?, ?, ?)`,
      [
        metric.serviceId,
        metric.timestamp,
        metric.cpuPercent,
        metric.memoryUsed,
        metric.memoryLimit,
        metric.networkRxBytes,
        metric.networkTxBytes,
      ]
    );
  }

  getMetrics(serviceId: number, limit = 100): IMetric[] {
    const rows = this.query(
      'SELECT * FROM metrics WHERE service_id = ? ORDER BY timestamp DESC LIMIT ?',
      [serviceId, limit]
    );
    return rows.map((row) => this.rowToMetric(row));
  }

  private rowToMetric(row: any): IMetric {
    return {
      id: Number(row.id || row[0]),
      serviceId: Number(row.service_id || row[1]),
      timestamp: Number(row.timestamp || row[2]),
      cpuPercent: Number(row.cpu_percent || row[3]),
      memoryUsed: Number(row.memory_used || row[4]),
      memoryLimit: Number(row.memory_limit || row[5]),
      networkRxBytes: Number(row.network_rx_bytes || row[6]),
      networkTxBytes: Number(row.network_tx_bytes || row[7]),
    };
  }

  // ============ Logs ============

  addLog(log: Omit<ILogEntry, 'id'>): void {
    this.query(
      'INSERT INTO logs (service_id, timestamp, message, level, source) VALUES (?, ?, ?, ?, ?)',
      [log.serviceId, log.timestamp, log.message, log.level, log.source]
    );
  }

  getLogs(serviceId: number, limit = 1000): ILogEntry[] {
    const rows = this.query(
      'SELECT * FROM logs WHERE service_id = ? ORDER BY timestamp DESC LIMIT ?',
      [serviceId, limit]
    );
    return rows.map((row) => this.rowToLog(row));
  }

  private rowToLog(row: any): ILogEntry {
    return {
      id: Number(row.id || row[0]),
      serviceId: Number(row.service_id || row[1]),
      timestamp: Number(row.timestamp || row[2]),
      message: String(row.message || row[3]),
      level: String(row.level || row[4]) as ILogEntry['level'],
      source: String(row.source || row[5]) as ILogEntry['source'],
    };
  }
}
