"use strict";
/**
 * Migration: Add TypeDoc plugin auto-discovery to documentation sites
 *
 * For each documentation site under unisphere/documentation/:
 *  - Creates plugins/discover-typedoc-plugins.mjs (re-discovery script)
 *  - Creates plugins/typedoc-plugins.ts (auto-discovered plugin config)
 *  - Updates docusaurus.config.ts to import from ./plugins/typedoc-plugins
 *  - Adds "discover-plugins" script to the site's package.json
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = update;
const devkit_1 = require("@nx/devkit");
const fs_1 = require("fs");
const path_1 = require("path");
const discover_typedoc_plugins_1 = require("../../generators/add-documentation/discover-typedoc-plugins");
const TYPEDOC_IMPORT = "import typedocPlugins from './plugins/typedoc-plugins';";
/**
 * Inserts the typedocPlugins import after the last import statement.
 */
function addTypedocImport(content) {
    if (content.includes(TYPEDOC_IMPORT))
        return content;
    const lines = content.split('\n');
    let lastImportIndex = -1;
    for (let i = 0; i < lines.length; i++) {
        if (lines[i].startsWith('import '))
            lastImportIndex = i;
    }
    if (lastImportIndex === -1)
        return content;
    lines.splice(lastImportIndex + 1, 0, TYPEDOC_IMPORT);
    return lines.join('\n');
}
/**
 * Replaces the plugins: [...] array (possibly multi-line) with plugins: typedocPlugins,
 * Uses bracket counting to handle nested arrays safely.
 */
function replacePluginsSection(content) {
    const pluginsMatch = content.match(/(\n[ \t]*plugins:\s*)\[/);
    if (!pluginsMatch || pluginsMatch.index === undefined)
        return content;
    const bracketStart = pluginsMatch.index + pluginsMatch[0].length - 1;
    // Count brackets to find closing ]
    let depth = 0;
    let i = bracketStart;
    while (i < content.length) {
        if (content[i] === '[')
            depth++;
        else if (content[i] === ']') {
            depth--;
            if (depth === 0)
                break;
        }
        i++;
    }
    // i is at closing ], consume optional comma and rest of line
    const lineEnd = content.indexOf('\n', i);
    const fullSection = content.substring(pluginsMatch.index + 1, // skip leading \n
    lineEnd + 1);
    const indent = pluginsMatch[1].replace('\n', '');
    return content.replace(fullSection, `${indent}typedocPlugins,\n`);
}
async function update(tree) {
    devkit_1.logger.info('🔄 Adding TypeDoc plugin auto-discovery to documentation sites...');
    // Read discover script from generator templates
    const discoverScriptContent = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../generators/add-documentation/templates/plugins/discover-typedoc-plugins.mjs'), 'utf-8');
    const docsBasePath = 'unisphere/documentation';
    if (!tree.exists(docsBasePath)) {
        devkit_1.logger.info('ℹ️ No documentation sites found, skipping');
        return;
    }
    const docsSites = tree.children(docsBasePath);
    if (docsSites.length === 0) {
        devkit_1.logger.info('ℹ️ No documentation sites found, skipping');
        return;
    }
    let createdCount = 0;
    let updatedCount = 0;
    let skippedCount = 0;
    for (const site of docsSites) {
        const sitePath = `${docsBasePath}/${site}`;
        try {
            // 1. Create plugins/discover-typedoc-plugins.mjs (idempotent)
            const discoverScriptPath = `${sitePath}/plugins/discover-typedoc-plugins.mjs`;
            const existingDiscoverScript = tree.exists(discoverScriptPath)
                ? tree.read(discoverScriptPath, 'utf-8') || ''
                : null;
            if (existingDiscoverScript?.trim() === discoverScriptContent.trim()) {
                devkit_1.logger.info(`ℹ️ ${discoverScriptPath} already up to date`);
            }
            else {
                tree.write(discoverScriptPath, discoverScriptContent);
                devkit_1.logger.info(`✅ ${existingDiscoverScript === null ? 'Created' : 'Updated'} ${discoverScriptPath}`);
            }
            // 2. Create plugins/typedoc-plugins.ts with auto-discovered content (idempotent)
            const typedocPluginsPath = `${sitePath}/plugins/typedoc-plugins.ts`;
            const discovered = (0, discover_typedoc_plugins_1.discoverTypedocPlugins)(tree, sitePath);
            const pluginsCode = (0, discover_typedoc_plugins_1.buildTypedocPluginsCode)(discovered);
            const typedocPluginsContent = `// 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[] = ${pluginsCode};\n` +
                `\n` +
                `export default typedocPlugins;\n`;
            const existingTypedocPlugins = tree.exists(typedocPluginsPath)
                ? tree.read(typedocPluginsPath, 'utf-8') || ''
                : null;
            if (existingTypedocPlugins?.trim() === typedocPluginsContent.trim()) {
                devkit_1.logger.info(`ℹ️ ${typedocPluginsPath} already up to date`);
            }
            else {
                tree.write(typedocPluginsPath, typedocPluginsContent);
                devkit_1.logger.info(`✅ ${existingTypedocPlugins === null ? 'Created' : 'Updated'} ${typedocPluginsPath} (${discovered.length} package(s) discovered)`);
            }
            // 3. Update docusaurus.config.ts
            const configPath = `${sitePath}/docusaurus.config.ts`;
            if (tree.exists(configPath)) {
                let configContent = tree.read(configPath, 'utf-8') || '';
                if (configContent.includes(TYPEDOC_IMPORT)) {
                    devkit_1.logger.info(`ℹ️ ${configPath} already migrated, skipping`);
                    skippedCount++;
                }
                else {
                    configContent = addTypedocImport(configContent);
                    configContent = replacePluginsSection(configContent);
                    tree.write(configPath, configContent);
                    devkit_1.logger.info(`✅ Updated ${configPath}`);
                    updatedCount++;
                }
            }
            else {
                devkit_1.logger.warn(`⚠️ ${configPath} not found, skipping config update`);
            }
            // 4. Update package.json: add discover-plugins script, typedoc-plugin-markdown, webpack override
            const pkgPath = `${sitePath}/package.json`;
            if (tree.exists(pkgPath)) {
                const pkg = (0, devkit_1.readJson)(tree, pkgPath);
                let pkgChanged = false;
                if (!pkg.scripts?.['discover-plugins']) {
                    pkg.scripts = pkg.scripts || {};
                    pkg.scripts['discover-plugins'] = 'node plugins/discover-typedoc-plugins.mjs';
                    pkgChanged = true;
                    devkit_1.logger.info(`✅ Added discover-plugins script to ${pkgPath}`);
                }
                else {
                    devkit_1.logger.info(`ℹ️ discover-plugins script already exists in ${pkgPath}`);
                }
                if (!pkg.devDependencies?.['typedoc-plugin-markdown']) {
                    pkg.devDependencies = pkg.devDependencies || {};
                    pkg.devDependencies['typedoc-plugin-markdown'] = '^4.8.0';
                    pkgChanged = true;
                    devkit_1.logger.info(`✅ Added typedoc-plugin-markdown to ${pkgPath}`);
                }
                if (!pkg.overrides?.['webpack']) {
                    pkg.overrides = pkg.overrides || {};
                    pkg.overrides['webpack'] = '5.105.4';
                    pkgChanged = true;
                    devkit_1.logger.info(`✅ Added webpack override to ${pkgPath}`);
                }
                if (pkgChanged) {
                    (0, devkit_1.writeJson)(tree, pkgPath, pkg);
                }
            }
            createdCount++;
        }
        catch (error) {
            const msg = error instanceof Error ? error.message : 'Unknown error';
            devkit_1.logger.warn(`⚠️ Failed to update ${sitePath}: ${msg}`);
        }
    }
    devkit_1.logger.info(`✅ Processed ${docsSites.length} documentation site(s): ${createdCount} processed, ${skippedCount} skipped`);
    await (0, devkit_1.formatFiles)(tree);
}
