#!/usr/bin/env node
/**
 * Auto-discovers publishable packages from .unisphere config and regenerates
 * plugins/typedoc-plugins.ts with updated docusaurus-plugin-typedoc entries.
 *
 * Run: npm run discover-plugins
 *
 * - Reads  <workspace-root>/.unisphere        for packages list
 * - Reads  <workspace-root>/tsconfig.base.json for npm package names
 * - Writes plugins/typedoc-plugins.ts
 *
 * Packages under the "local" scope are excluded (internal-only packages).
 */

import { readFileSync, writeFileSync, existsSync } from 'fs';
import { join, relative, dirname } from 'path';
import { fileURLToPath } from 'url';

const DOCUMENTED_SCOPES = [
  'kaltura-corp',
  'kaltura-apps',
  'kaltura-ui',
  'kaltura-sdk',
  'unisphere',
];

// This script lives at <docs-site>/plugins/discover-typedoc-plugins.mjs
const pluginsDir = dirname(fileURLToPath(import.meta.url));
const docsSiteRoot = join(pluginsDir, '..');

// Walk up from docs site to find workspace root (where .unisphere lives)
function findWorkspaceRoot(startDir) {
  let dir = startDir;
  while (true) {
    if (existsSync(join(dir, '.unisphere'))) return dir;
    const parent = dirname(dir);
    if (parent === dir) {
      throw new Error(
        'Could not find .unisphere — are you inside a Unisphere workspace?'
      );
    }
    dir = parent;
  }
}

const workspaceRoot = findWorkspaceRoot(docsSiteRoot);

// Parse workspace configs
const unisphere = JSON.parse(
  readFileSync(join(workspaceRoot, '.unisphere'), 'utf-8')
);
const tsconfig = JSON.parse(
  readFileSync(join(workspaceRoot, 'tsconfig.base.json'), 'utf-8')
);
const tsconfigPaths = tsconfig?.compilerOptions?.paths ?? {};
const packages = unisphere?.elements?.packages ?? {};

// Build reverse lookup: "sourceRoot/src/index.ts" → npm package name
const pathToPackageName = {};
for (const [pkgName, paths] of Object.entries(tsconfigPaths)) {
  if (Array.isArray(paths)) {
    for (const p of paths) {
      pathToPackageName[p] = pkgName;
    }
  }
}

function findPackageName(sourceRoot) {
  return pathToPackageName[`${sourceRoot}/src/index.ts`] ?? null;
}

function shortName(pkgName) {
  return pkgName.split('/').pop();
}

// Discover plugins
const discovered = [];
for (const [, pkgConfig] of Object.entries(packages)) {
  const sourceRoot = pkgConfig?.sourceRoot;
  if (!sourceRoot) continue;

  // Expected sourceRoot format: unisphere/packages/<scope>/<name>
  const parts = sourceRoot.split('/');
  if (parts.length < 4) continue;
  const scope = parts[2];

  if (!DOCUMENTED_SCOPES.includes(scope)) continue;

  const pkgName = findPackageName(sourceRoot);
  if (!pkgName) {
    console.warn(`⚠️  No tsconfig path found for ${sourceRoot} — skipping`);
    continue;
  }

  const short = shortName(pkgName);
  // Relative path from docs site root to the package folder
  const relBase = relative(
    docsSiteRoot,
    join(workspaceRoot, sourceRoot)
  ).replace(/\\/g, '/');

  discovered.push({
    id: `api-${short}`,
    packageName: pkgName,
    entryPoints: `${relBase}/src/index.ts`,
    tsconfig: `${relBase}/tsconfig.json`,
    out: `docs/api/${short}/v1`,
  });
}

// Serialise to TypeScript
function pluginsToTs(plugins) {
  if (plugins.length === 0) return '[]';

  const entries = plugins
    .map(
      (p) =>
        `  // ${p.packageName}\n` +
        `  [\n` +
        `    'docusaurus-plugin-typedoc',\n` +
        `    {\n` +
        `      id: '${p.id}',\n` +
        `      entryPoints: ['${p.entryPoints}'],\n` +
        `      tsconfig: '${p.tsconfig}',\n` +
        `      out: '${p.out}',\n` +
        `      readme: 'none',\n` +
        `      excludePrivate: true,\n` +
        `      excludeProtected: true,\n` +
        `      excludeInternal: true,\n` +
        `      disableSources: true,\n` +
        `    },\n` +
        `  ]`
    )
    .join(',\n');

  return `[\n${entries},\n]`;
}

const content =
  `// Auto-generated by plugins/discover-typedoc-plugins.mjs\n` +
  `// Run "npm run discover-plugins" to regenerate\n` +
  `\n` +
  `// eslint-disable-next-line @typescript-eslint/no-explicit-any\n` +
  `const typedocPlugins: any[] = ${pluginsToTs(discovered)};\n` +
  `\n` +
  `export default typedocPlugins;\n`;

const outPath = join(pluginsDir, 'typedoc-plugins.ts');
writeFileSync(outPath, content, 'utf-8');

console.log(
  `✅ Discovered ${discovered.length} package(s) → plugins/typedoc-plugins.ts`
);
for (const p of discovered) {
  console.log(`   • ${p.packageName} → ${p.out}`);
}
