#!/usr/bin/env node
/**
 * MCP Factory — Batch Protocol Validation
 * Runs mcp-jest validate on all 30 servers, collects compliance scores.
 */

import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
import { execSync } from 'child_process';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const FACTORY_ROOT = resolve(__dirname, '..');
const registry = JSON.parse(readFileSync(resolve(FACTORY_ROOT, 'server-registry.json'), 'utf-8'));
const SERVERS_ROOT = resolve(FACTORY_ROOT, registry.servers_root);

const CONFIGS_DIR = resolve(FACTORY_ROOT, 'test-configs');
const REPORTS_DIR = resolve(FACTORY_ROOT, 'reports');
mkdirSync(REPORTS_DIR, { recursive: true });

const results = [];
let totalScore = 0;

for (const [name, meta] of Object.entries(registry.servers)) {
  const configPath = resolve(CONFIGS_DIR, `${name}.json`);

  if (!existsSync(configPath)) {
    console.log(`⚠️  ${name}: No config — run discover first`);
    results.push({ name, score: null, level: 'SKIPPED', issues: ['No config file'] });
    continue;
  }

  try {
    console.log(`🔬 Validating ${name}...`);
    const output = execSync(`mcp-jest validate --config "${configPath}" 2>&1`, {
      timeout: 30000,
      encoding: 'utf-8',
      stdio: ['pipe', 'pipe', 'pipe']
    });

    // Parse score from output
    const scoreMatch = output.match(/Score:\s*(\d+)\/100/);
    const levelMatch = output.match(/Level:\s*(\S+)/);
    const failedTests = [...output.matchAll(/❌\s*\[(\w+)\s*\]\s*(.+)/g)].map(m => m[2].trim());

    const score = scoreMatch ? parseInt(scoreMatch[1]) : null;
    const level = levelMatch ? levelMatch[1] : 'UNKNOWN';

    totalScore += score || 0;
    results.push({ name, score, level, issues: failedTests });

    const emoji = score >= 95 ? '🟢' : score >= 80 ? '🟡' : '🔴';
    console.log(`   ${emoji} ${name}: ${score}/100 (${level}) ${failedTests.length > 0 ? '— ' + failedTests.length + ' issue(s)' : ''}`);
  } catch (err) {
    // mcp-jest validate exits with code 1 for non-compliant, but still has output
    const output = err.stdout?.toString() || err.stderr?.toString() || '';

    const scoreMatch = output.match(/Score:\s*(\d+)\/100/);
    const levelMatch = output.match(/Level:\s*(\S+)/);
    const failedTests = [...output.matchAll(/❌\s*\[(\w+)\s*\]\s*(.+)/g)].map(m => m[2].trim());

    const score = scoreMatch ? parseInt(scoreMatch[1]) : 0;
    const level = levelMatch ? levelMatch[1] : 'ERROR';

    totalScore += score;
    results.push({ name, score, level, issues: failedTests.length > 0 ? failedTests : [output.split('\n')[0]] });

    const emoji = score >= 95 ? '🟢' : score >= 80 ? '🟡' : '🔴';
    console.log(`   ${emoji} ${name}: ${score}/100 (${level}) ${failedTests.length > 0 ? '— ' + failedTests.length + ' issue(s)' : ''}`);
  }
}

// Summary
const validResults = results.filter(r => r.score !== null);
const avgScore = validResults.length > 0 ? Math.round(totalScore / validResults.length) : 0;
const perfect = validResults.filter(r => r.score >= 95).length;
const good = validResults.filter(r => r.score >= 80 && r.score < 95).length;
const needsWork = validResults.filter(r => r.score < 80).length;

console.log('\n' + '═'.repeat(60));
console.log('        MCP FACTORY — COMPLIANCE REPORT');
console.log('═'.repeat(60));
console.log(`\nServers validated: ${validResults.length}/${results.length}`);
console.log(`Average score:    ${avgScore}/100`);
console.log(`🟢 Compliant (95+):  ${perfect}`);
console.log(`🟡 Near (80-94):     ${good}`);
console.log(`🔴 Needs work (<80): ${needsWork}`);

// Common issues
const allIssues = results.flatMap(r => r.issues);
const issueFreq = {};
for (const issue of allIssues) {
  issueFreq[issue] = (issueFreq[issue] || 0) + 1;
}
const sortedIssues = Object.entries(issueFreq).sort((a, b) => b[1] - a[1]);

if (sortedIssues.length > 0) {
  console.log('\nMost common issues:');
  for (const [issue, count] of sortedIssues.slice(0, 5)) {
    console.log(`  ${count}x — ${issue}`);
  }
}

// Write report
const report = {
  date: new Date().toISOString(),
  summary: { total: results.length, validated: validResults.length, avgScore, perfect, good, needsWork },
  commonIssues: sortedIssues,
  servers: results
};

const reportPath = resolve(REPORTS_DIR, `compliance-${new Date().toISOString().split('T')[0]}.json`);
writeFileSync(reportPath, JSON.stringify(report, null, 2));

// Also write markdown
let md = `# MCP Factory Compliance Report\n\n`;
md += `**Date:** ${new Date().toLocaleDateString()}\n`;
md += `**Average Score:** ${avgScore}/100\n\n`;
md += `| Server | Score | Level | Issues |\n|--------|-------|-------|--------|\n`;
for (const r of results) {
  const emoji = r.score >= 95 ? '🟢' : r.score >= 80 ? '🟡' : r.score === null ? '⚪' : '🔴';
  md += `| ${emoji} ${r.name} | ${r.score ?? '-'}/100 | ${r.level} | ${r.issues.join('; ') || 'None'} |\n`;
}

const mdPath = resolve(REPORTS_DIR, `compliance-${new Date().toISOString().split('T')[0]}.md`);
writeFileSync(mdPath, md);
console.log(`\nReports saved:\n  ${reportPath}\n  ${mdPath}`);
