"use strict";
/**
 * Migration: Add local runtimes setup
 *
 * For each local application (sourceRoot containing '/server'):
 * 1. Creates setup-local-runtimes.ts with experience name from .unisphere
 * 2. Imports and calls setupLocalRuntimes() in main.tsx
 * 3. Adds LOCAL_RUNTIMES env var to webpack DefinePlugin
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = update;
const devkit_1 = require("@nx/devkit");
const path_1 = require("path");
function generateSetupLocalRuntimes(experienceName) {
    return `export function setupLocalRuntimes() {
  if (!process.env.LOCAL_RUNTIMES) return;

  const runtimes: Record<string, { token: string; baseEnvName: string }> = {};
  process.env.LOCAL_RUNTIMES.split(',').forEach((entry) => {
    const [name, port] = entry.split('@');
    if (name && port) {
      runtimes[name] = { token: port, baseEnvName: '' };
    }
  });

  const overrides = {
    baseEnvName: '',
    mode: 'integration',
    options: { verbose: 'inherit' },
    baseEnvScope: { core: 'inherit', presets: 'inherit' },
    runtimes: {
      '${experienceName}': runtimes,
    },
  };

  (window as any).unisphereRuntimeOverrides = btoa(JSON.stringify(overrides));
}
`;
}
function addImportToMainTsx(content) {
    const importLine = "import { setupLocalRuntimes } from './setup-local-runtimes';";
    const callLine = 'setupLocalRuntimes();';
    if (content.includes('setupLocalRuntimes')) {
        return content;
    }
    // Find the last import statement
    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) {
        // No imports found, add at the top
        return `${importLine}\n\n${callLine}\n\n${content}`;
    }
    // Insert after the last import
    lines.splice(lastImportIndex + 1, 0, importLine, '', callLine);
    return lines.join('\n');
}
function addLocalRuntimesToDefinePlugin(content) {
    const entry = "'process.env.LOCAL_RUNTIMES': JSON.stringify(process.env.LOCAL_RUNTIMES),";
    if (content.includes('LOCAL_RUNTIMES')) {
        return content;
    }
    // Find the DefinePlugin block and add before its closing })
    const definePluginMatch = content.match(/new DefinePlugin\(\{/);
    if (!definePluginMatch || definePluginMatch.index === undefined) {
        return content;
    }
    // Find the closing }) of DefinePlugin
    const startIndex = definePluginMatch.index;
    let braceCount = 0;
    let closingIndex = -1;
    for (let i = startIndex; i < content.length; i++) {
        if (content[i] === '{')
            braceCount++;
        if (content[i] === '}') {
            braceCount--;
            if (braceCount === 0) {
                closingIndex = i;
                break;
            }
        }
    }
    if (closingIndex === -1) {
        return content;
    }
    const indent = '      ';
    // Insert the new entry before the closing }
    return content.substring(0, closingIndex).trimEnd() + '\n' +
        `${indent}${entry}\n` +
        '    ' + content.substring(closingIndex);
}
async function update(tree) {
    devkit_1.logger.info('🔄 Adding local runtimes setup to local applications...');
    if (!tree.exists('.unisphere')) {
        devkit_1.logger.warn('⚠️ No .unisphere file found, skipping');
        return;
    }
    const config = (0, devkit_1.readJson)(tree, '.unisphere');
    const experienceName = `unisphere.${config.type}.${config.name}`;
    const applications = config.elements?.applications;
    if (!applications || Object.keys(applications).length === 0) {
        devkit_1.logger.info('ℹ️ No applications found, skipping');
        return;
    }
    let updatedCount = 0;
    for (const [appName, appConfig] of Object.entries(applications)) {
        const { sourceRoot } = appConfig;
        // Only process server applications
        if (!sourceRoot.includes('/server/')) {
            devkit_1.logger.info(`ℹ️ ${appName}: Not a server application, local was already migrated. skipping`);
            continue;
        }
        const setupFilePath = (0, path_1.join)(sourceRoot, 'src', 'setup-local-runtimes.ts');
        const mainTsxPath = (0, path_1.join)(sourceRoot, 'src', 'main.tsx');
        const webpackPath = (0, path_1.join)(sourceRoot, 'webpack.config.js');
        // 1. Create setup-local-runtimes.ts
        if (tree.exists(setupFilePath)) {
            devkit_1.logger.info(`ℹ️ ${appName}: setup-local-runtimes.ts already exists, skipping`);
        }
        else {
            tree.write(setupFilePath, generateSetupLocalRuntimes(experienceName));
            devkit_1.logger.info(`✅ ${appName}: Created setup-local-runtimes.ts`);
        }
        // 2. Modify main.tsx
        if (!tree.exists(mainTsxPath)) {
            devkit_1.logger.warn(`⚠️ ${appName}: No main.tsx found, skipping`);
            continue;
        }
        const mainContent = tree.read(mainTsxPath, 'utf-8') || '';
        const updatedMain = addImportToMainTsx(mainContent);
        if (updatedMain !== mainContent) {
            tree.write(mainTsxPath, updatedMain);
            devkit_1.logger.info(`✅ ${appName}: Added setupLocalRuntimes import to main.tsx`);
        }
        else {
            devkit_1.logger.info(`ℹ️ ${appName}: main.tsx already has setupLocalRuntimes`);
        }
        // 3. Modify webpack.config.js
        if (!tree.exists(webpackPath)) {
            devkit_1.logger.warn(`⚠️ ${appName}: No webpack.config.js found, skipping`);
            continue;
        }
        const webpackContent = tree.read(webpackPath, 'utf-8') || '';
        const updatedWebpack = addLocalRuntimesToDefinePlugin(webpackContent);
        if (updatedWebpack !== webpackContent) {
            tree.write(webpackPath, updatedWebpack);
            devkit_1.logger.info(`✅ ${appName}: Added LOCAL_RUNTIMES to DefinePlugin`);
        }
        else {
            devkit_1.logger.info(`ℹ️ ${appName}: webpack.config.js already has LOCAL_RUNTIMES`);
        }
        updatedCount++;
    }
    await (0, devkit_1.formatFiles)(tree);
    devkit_1.logger.info(`\n✅ Done: ${updatedCount} local application(s) updated with local runtimes setup (experience: ${experienceName})`);
}
