import * as fs from 'fs';
import * as path from 'path';

interface BenchmarkRow {
  idproc: string;
  descproc: string;
  percentile: string;
  nbproc: string;
  perf: string;
}

const BENCHMARK_FILES = [
  'pts-nginx.csv',
  'pts-apache.csv',
  'pts-apache-siege.csv',
  'pts-node-octane.csv',
  'pts-node-express-loadtest.csv',
  'pts-phpbench.csv',
  'pts-redis.csv',
  'pts-mysqlslap.csv',
  'pts-compress-7zip.csv',
  'pts-compress-pbzip2.csv',
  'pts-compress-gzip.csv',
  'pts-postmark.csv',
  'pts-compilebench.csv',
  'pts-c-ray.csv',
  'pts-coremark.csv',
  'pts-byte.csv',
  'pts-encode-mp3.csv',
  'pts-encode-flac.csv',
  'pts-x264.csv',
  'pts-build-imagemagick.csv',
  'pts-build-nodejs.csv',
  'pts-build-php.csv',
];

function parseCSV(content: string): BenchmarkRow[] {
  const lines = content.trim().split('\n');
  const header = lines[0].split(',');
  const rows: BenchmarkRow[] = [];

  for (let i = 1; i < lines.length; i++) {
    const values = lines[i].split(',');
    if (values.length >= 6) {
      rows.push({
        idproc: values[1],
        descproc: values[2],
        percentile: values[3],
        nbproc: values[4],
        perf: values[5],
      });
    }
  }
  return rows;
}

function parsePerf(perf: string): { score: number; deviation: number | null } {
  // Format: "496096 +/- 4671" or "496096"
  const match = perf.match(/^([\d.]+)\s*(?:\+\/-\s*([\d.]+))?$/);
  if (match) {
    return {
      score: parseFloat(match[1]),
      deviation: match[2] ? parseFloat(match[2]) : null,
    };
  }
  return { score: 0, deviation: null };
}

function parsePercentile(percentile: string): number {
  // Format: "100th", "98th", "95th", etc.
  const match = percentile.match(/^(\d+)/);
  return match ? parseInt(match[1]) : 0;
}

function extractVendor(name: string): string {
  if (name.toLowerCase().includes('amd')) return 'AMD';
  if (name.toLowerCase().includes('intel')) return 'Intel';
  if (name.toLowerCase().includes('arm')) return 'ARM';
  if (name.toLowerCase().includes('apple')) return 'Apple';
  return 'Unknown';
}

function extractCores(name: string): number | null {
  // Try to extract core count from name
  const match = name.match(/(\d+)-Core/i);
  return match ? parseInt(match[1]) : null;
}

function escapeSQL(str: string): string {
  return str.replace(/'/g, "''");
}

async function main() {
  const dataDir = path.join(__dirname, '../benchmark-data/data/suite');
  const processors = new Map<string, { name: string; vendor: string; cores: number | null }>();
  const benchmarks: Array<{
    procId: string;
    benchmarkType: string;
    score: number;
    deviation: number | null;
    percentile: number;
    sampleCount: number;
  }> = [];

  for (const file of BENCHMARK_FILES) {
    const filePath = path.join(dataDir, file);
    if (!fs.existsSync(filePath)) {
      console.error(`File not found: ${filePath}`);
      continue;
    }

    const content = fs.readFileSync(filePath, 'utf-8');
    const rows = parseCSV(content);
    const benchmarkType = file.replace('.csv', '');

    for (const row of rows) {
      // Store processor info
      if (!processors.has(row.idproc)) {
        processors.set(row.idproc, {
          name: row.descproc,
          vendor: extractVendor(row.descproc),
          cores: extractCores(row.descproc),
        });
      }

      // Parse performance
      const { score, deviation } = parsePerf(row.perf);
      if (score > 0) {
        benchmarks.push({
          procId: row.idproc,
          benchmarkType,
          score,
          deviation,
          percentile: parsePercentile(row.percentile),
          sampleCount: parseInt(row.nbproc) || 1,
        });
      }
    }
  }

  // Generate SQL
  let sql = '-- Generated benchmark data\n\n';

  // Insert processors
  sql += '-- Insert processors\n';
  const procArray = Array.from(processors.entries());
  for (const [procId, info] of procArray) {
    const cores = info.cores !== null ? info.cores : 'NULL';
    sql += `INSERT OR IGNORE INTO processors (proc_id, name, vendor, cores) VALUES ('${escapeSQL(procId)}', '${escapeSQL(info.name)}', '${info.vendor}', ${cores});\n`;
  }

  sql += '\n-- Insert benchmark results\n';
  for (const b of benchmarks) {
    const deviation = b.deviation !== null ? b.deviation : 'NULL';
    sql += `INSERT OR IGNORE INTO benchmark_results (processor_id, benchmark_type_id, score, score_deviation, percentile, sample_count)
SELECT p.id, bt.id, ${b.score}, ${deviation}, ${b.percentile}, ${b.sampleCount}
FROM processors p, benchmark_types bt
WHERE p.proc_id = '${escapeSQL(b.procId)}' AND bt.name = '${b.benchmarkType}';\n`;
  }

  // Output summary
  console.log(`Processed ${processors.size} processors`);
  console.log(`Processed ${benchmarks.length} benchmark results`);

  // Write SQL file
  fs.writeFileSync(path.join(__dirname, '../benchmark-seed.sql'), sql);
  console.log('Generated benchmark-seed.sql');
}

main().catch(console.error);
