#!/usr/bin/env node
/**
 * skyeye/scripts/weekly-scan.js
 * 天眼周六大巡检主脚本 — 汇总所有 Phase 结果，生成报告
 * Phase 5 of weekly scan: Generate Report
 */

const fs = require('fs');
const path = require('path');

const ROOT = path.resolve(__dirname, '../..');
const SKYEYE_DIR = path.resolve(__dirname, '..');
const SCAN_REPORT_DIR = path.join(SKYEYE_DIR, 'scan-report');
const LOGS_DIR = path.join(SKYEYE_DIR, 'logs');

function getTimestamp() {
  return new Date().toISOString();
}

function getDateStr() {
  return new Date().toISOString().slice(0, 10).replace(/-/g, '');
}

function getBeijingTime() {
  return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
}

function loadJSON(filePath) {
  try {
    return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch (e) {
    return null;
  }
}

function saveJSON(filePath, data) {
  fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
}

function findLatestLog(logDir, prefix) {
  if (!fs.existsSync(logDir)) return null;
  const files = fs.readdirSync(logDir)
    .filter(f => f.startsWith(prefix) && f.endsWith('.json'))
    .sort()
    .reverse();
  if (files.length === 0) return null;
  return loadJSON(path.join(logDir, files[0]));
}

function countGuards() {
  const guardsDir = path.join(SKYEYE_DIR, 'guards');
  if (!fs.existsSync(guardsDir)) return { total: 0, active: 0, suspended: 0 };

  const files = fs.readdirSync(guardsDir)
    .filter(f => f.endsWith('.json') && f !== 'guard-template.json');

  let active = 0;
  let suspended = 0;

  for (const file of files) {
    const guard = loadJSON(path.join(guardsDir, file));
    if (guard) {
      if (guard.status === 'active') active++;
      else if (guard.status === 'suspended' || guard.mode === 'suspended') suspended++;
    }
  }

  return { total: files.length, active, suspended };
}

function generateReport() {
  console.log(`[SkyEye Weekly Scan] Generating weekly scan report`);
  console.log(`[SkyEye Weekly Scan] Beijing Time: ${getBeijingTime()}`);

  const dateStr = getDateStr();
  const weeklyLogDir = path.join(LOGS_DIR, 'weekly');

  // Load Phase results from logs
  const scanResult = findLatestLog(weeklyLogDir, 'scan-');
  const auditResult = findLatestLog(weeklyLogDir, 'quota-audit-');
  const optimizeResult = findLatestLog(weeklyLogDir, 'optimize-');
  const healResult = findLatestLog(weeklyLogDir, 'self-heal-');

  const guardStatus = countGuards();

  // Calculate next Saturday 20:00 CST
  const now = new Date();
  const dayOfWeek = now.getUTCDay();
  const daysUntilSaturday = (6 - dayOfWeek + 7) % 7 || 7;
  const nextSaturday = new Date(now);
  nextSaturday.setUTCDate(now.getUTCDate() + daysUntilSaturday);
  nextSaturday.setUTCHours(12, 0, 0, 0); // 20:00 CST = 12:00 UTC

  const report = {
    report_id: `SKYEYE-SCAN-${dateStr}`,
    scan_time: getTimestamp(),
    scan_time_beijing: getBeijingTime(),
    scan_duration_seconds: 0,

    infrastructure_status: {
      total_services: 5,
      healthy: 5,
      degraded: 0,
      down: 0
    },

    quota_status: {
      github_actions: {
        used_percent: auditResult?.services?.github_actions?.usage_percent || 0,
        remaining_minutes: 2000,
        trend: 'stable',
        recommendation: 'maintain_current_frequency'
      },
      google_drive: {
        used_percent: auditResult?.services?.google_drive?.usage_percent || 0,
        recommendation: 'no_action_needed'
      },
      notion_api: {
        status: auditResult?.services?.notion_api?.status || 'healthy',
        recommendation: 'no_action_needed'
      },
      gemini: {
        used_percent: auditResult?.services?.gemini?.usage_percent || 0,
        recommendation: 'no_action_needed'
      }
    },

    guard_status: {
      total_guards: guardStatus.total,
      active: guardStatus.active,
      suspended: guardStatus.suspended,
      adjustments_made: optimizeResult?.adjustments || []
    },

    self_heal_actions: {
      files_cleaned: healResult?.summary?.files_cleaned || 0,
      configs_repaired: healResult?.summary?.configs_repaired || 0,
      guards_restarted: healResult?.summary?.guards_restarted || 0
    },

    phase_details: {
      phase1_scan: scanResult?.summary || null,
      phase2_audit: auditResult?.overall_status || null,
      phase3_optimize: optimizeResult?.summary || null,
      phase4_heal: healResult?.summary || null
    },

    alerts: [],
    human_action_required: [],

    hibernation_status: {
      deployed: fs.existsSync(path.join(ROOT, 'skyeye/hibernation')),
      daily_checkpoints: (() => {
        const cpDir = path.join(ROOT, 'skyeye/hibernation/checkpoints');
        try {
          return fs.existsSync(cpDir)
            ? fs.readdirSync(cpDir).filter(f => f.startsWith('daily-cp-') && f.endsWith('.json')).length
            : 0;
        } catch (e) { return 0; }
      })(),
      weekly_snapshots: (() => {
        const snapDir = path.join(ROOT, 'skyeye/hibernation/weekly-snapshots');
        try {
          return fs.existsSync(snapDir)
            ? fs.readdirSync(snapDir).filter(f => f.startsWith('weekly-snapshot-') && f.endsWith('.json')).length
            : 0;
        } catch (e) { return 0; }
      })(),
      upgrade_packs: (() => {
        const upDir = path.join(ROOT, 'skyeye/hibernation/upgrade-packs');
        try {
          return fs.existsSync(upDir)
            ? fs.readdirSync(upDir).filter(f => f.startsWith('upgrade-pack-') && f.endsWith('.json')).length
            : 0;
        } catch (e) { return 0; }
      })()
    },

    next_scan: nextSaturday.toISOString()
  };

  // Collect alerts from all phases
  if (scanResult?.issues) {
    for (const issue of scanResult.issues) {
      if (issue.severity === 'error') {
        report.alerts.push(issue.detail);
      }
    }
  }
  if (auditResult?.services) {
    for (const [, svc] of Object.entries(auditResult.services)) {
      report.alerts.push(...(svc.alerts || []));
    }
  }

  // Determine infrastructure health
  if (report.alerts.length > 0) {
    const criticalAlerts = report.alerts.filter(a =>
      a.includes('90%') || a.includes('critical') || a.includes('严重')
    );
    if (criticalAlerts.length > 0) {
      report.infrastructure_status.degraded = criticalAlerts.length;
      report.infrastructure_status.healthy -= criticalAlerts.length;
    }
  }

  // Write report
  if (!fs.existsSync(SCAN_REPORT_DIR)) fs.mkdirSync(SCAN_REPORT_DIR, { recursive: true });
  const reportPath = path.join(SCAN_REPORT_DIR, `${dateStr}-weekly-scan.json`);
  saveJSON(reportPath, report);

  console.log(`[SkyEye Weekly Scan] Report generated: ${reportPath}`);
  console.log(`[SkyEye Weekly Scan] Report ID: ${report.report_id}`);
  console.log(`[SkyEye Weekly Scan] Guards: ${guardStatus.active}/${guardStatus.total} active`);
  console.log(`[SkyEye Weekly Scan] Alerts: ${report.alerts.length}`);
  console.log(`[SkyEye Weekly Scan] Human action required: ${report.human_action_required.length}`);
  console.log(`[SkyEye Weekly Scan] Next scan: ${report.next_scan}`);

  console.log('---REPORT_JSON---');
  console.log(JSON.stringify(report, null, 2));

  return report;
}

generateReport();
