/**
 * 批量将 examples/sample-center/xml 下的 BaskReport XML 转为 ReportIR JSON。
 *
 * - 递归遍历，保持相同的子目录结构，输出到 examples/sample-center/json。
 * - <dashboard> 根（仪表盘/图表）不在 IR 承载范围内，跳过并打印提示。
 * - 每个产物过 ajv schema 校验，失败的文件打印错误并计入失败数。
 *
 * 用法：npm run xml2json
 */
import { promises as fs } from 'node:fs';
import * as path from 'node:path';
import { parseReport } from '../src/core/xml/parse.js';
import { validateIR } from '../src/core/validate/schemaValidator.js';

const SRC_ROOT = path.resolve('examples/sample-center/xml');
const OUT_ROOT = path.resolve('examples/sample-center/json');

let okCount = 0;
let skipCount = 0;
let failCount = 0;
const failed: Array<{ file: string; reason: string }> = [];

async function walk(dir: string, rel: string): Promise<void> {
  const entries = await fs.readdir(dir, { withFileTypes: true });
  for (const ent of entries) {
    const full = path.join(dir, ent.name);
    const nextRel = path.join(rel, ent.name);
    if (ent.isDirectory()) {
      await walk(full, nextRel);
    } else if (ent.isFile() && ent.name.toLowerCase().endsWith('.xml')) {
      await convertFile(full, nextRel);
    }
  }
}

async function convertFile(full: string, rel: string): Promise<void> {
  const xml = await fs.readFile(full, 'utf-8');
  let ir: ReturnType<typeof parseReport>;
  try {
    ir = parseReport(xml);
  } catch (e) {
    failCount++;
    failed.push({ file: rel, reason: `parse 异常: ${(e as Error).message}` });
    return;
  }

  if (ir === null) {
    skipCount++;
    console.log(`  跳过(仪表盘/图表): ${rel}`);
    return;
  }

  // schema 校验
  try {
    validateIR(ir);
  } catch (e) {
    failCount++;
    failed.push({ file: rel, reason: (e as Error).message.split('\n').slice(0, 3).join(' | ') });
    return;
  }

  const outRel = rel.replace(/\.xml$/i, '.json');
  const outPath = path.join(OUT_ROOT, outRel);
  await fs.mkdir(path.dirname(outPath), { recursive: true });
  await fs.writeFile(outPath, JSON.stringify(ir, null, 2), 'utf-8');
  okCount++;
  console.log(`  转换: ${rel} -> ${outRel}`);
}

async function main(): Promise<void> {
  console.log(`源目录: ${SRC_ROOT}`);
  console.log(`输出目录: ${OUT_ROOT}`);
  await fs.mkdir(OUT_ROOT, { recursive: true });
  await walk(SRC_ROOT, '');

  console.log('\n==== 汇总 ====');
  console.log(`  成功: ${okCount}`);
  console.log(`  跳过(dashboard): ${skipCount}`);
  console.log(`  失败: ${failCount}`);
  if (failed.length) {
    console.log('\n失败明细:');
    for (const f of failed) console.log(`  - ${f.file}: ${f.reason}`);
    process.exitCode = 1;
  }
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
