import fs from "node:fs";
/**
 * Returns the code for the `runtime.js` module
 */
export function createRuntimeFile(args) {
    const urlPatterns = args.compilerOptions.urlPatterns ?? [];
    const routeStrategies = args.compilerOptions.routeStrategies ?? [];
    let defaultUrlPatternUsed = false;
    // add default urlPatterns for a good out of the box experience
    if (args.compilerOptions.urlPatterns === undefined) {
        defaultUrlPatternUsed = true;
        urlPatterns.push({
            pattern: `:protocol://:domain(.*)::port?/:path(.*)?`,
            localized: [],
        });
        for (const locale of args.locales) {
            if (locale === args.baseLocale) {
                continue;
            }
            urlPatterns[0]?.localized.push([
                locale,
                `:protocol://:domain(.*)::port?/${locale}/:path(.*)?`,
            ]);
        }
        urlPatterns[0]?.localized.push([
            args.baseLocale,
            `:protocol://:domain(.*)::port?/:path(.*)?`,
        ]);
    }
    const strategiesUsedByRoutes = routeStrategies.flatMap((routeStrategy) => "strategy" in routeStrategy ? routeStrategy.strategy : []);
    const allUsedStrategies = new Set([
        ...args.compilerOptions.strategy,
        ...strategiesUsedByRoutes,
    ]);
    const needsUrlPatternPolyfill = !defaultUrlPatternUsed || routeStrategies.length > 0;
    // verify that urlPatterns' locales are valid
    for (const urlPattern of urlPatterns) {
        for (const [locale] of urlPattern.localized) {
            if (!args.locales.includes(locale)) {
                throw new Error(`Invalid locale "${locale}" in urlPatterns. It must be one of the locales defined in the "locales" array.`);
            }
        }
    }
    const code = `
${needsUrlPatternPolyfill ? `import "@inlang/paraglide-js/urlpattern-polyfill";` : "/** @type {any} */\nconst URLPattern = {}"}

${injectCode("./variables.js")
        .replace(`export const baseLocale = "en";`, `export const baseLocale = "${args.baseLocale}";`)
        .replace(`export const locales = /** @type {readonly string[]} */ (["en", "de"]);`, `export const locales = /** @type {const} */ (${JSON.stringify(args.locales)});`)
        .replace(`export const strategy = ["globalVariable"];`, `export const strategy = ${JSON.stringify(args.compilerOptions.strategy, null, 2)};`)
        .replace(`<cookie-name>`, `${args.compilerOptions.cookieName}`)
        .replace(`60 * 60 * 24 * 400`, `${args.compilerOptions.cookieMaxAge}`)
        .replace(`<cookie-domain>`, `${args.compilerOptions.cookieDomain}`)
        .replace(`export const routeStrategies = [];`, `export const routeStrategies = ${JSON.stringify(routeStrategies, null, 2)};`)
        .replace(`export const TREE_SHAKE_COOKIE_STRATEGY_USED = false;`, `const TREE_SHAKE_COOKIE_STRATEGY_USED = ${allUsedStrategies.has("cookie")};`)
        .replace(`export const TREE_SHAKE_URL_STRATEGY_USED = false;`, `const TREE_SHAKE_URL_STRATEGY_USED = ${allUsedStrategies.has("url")};`)
        .replace(`export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = false;`, `const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = ${allUsedStrategies.has("globalVariable")};`)
        .replace(`export const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = false;`, `const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = ${allUsedStrategies.has("preferredLanguage")};`)
        .replace(`export const urlPatterns = [];`, `export const urlPatterns = ${JSON.stringify(urlPatterns, null, 2)};`)
        .replace(`export const disableAsyncLocalStorage = false;`, `export const disableAsyncLocalStorage = ${args.compilerOptions.disableAsyncLocalStorage};`)
        .replace(`export const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = false;`, `const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = ${defaultUrlPatternUsed};`)
        .replace(`export const experimentalMiddlewareLocaleSplitting = false;`, `export const experimentalMiddlewareLocaleSplitting = ${args.compilerOptions.experimentalMiddlewareLocaleSplitting};`)
        .replace(`export const isServer = typeof window === "undefined";`, `export const isServer = ${args.compilerOptions.isServer};`)
        .replace(`export const experimentalStaticLocale = undefined;`, args.compilerOptions.experimentalStaticLocale
        ? `export const experimentalStaticLocale = assertIsLocale(${args.compilerOptions.experimentalStaticLocale});`
        : `export const experimentalStaticLocale = undefined;`)
        .replace(`export const localStorageKey = "PARAGLIDE_LOCALE";`, `export const localStorageKey = "${args.compilerOptions.localStorageKey}";`)
        .replace(`export const TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED = false;`, `const TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED = ${allUsedStrategies.has("localStorage")};`)}

/** @type {any} */ (globalThis).__paraglide =
	/** @type {any} */ (globalThis).__paraglide ?? {};
/** @type {any} */ (globalThis).__paraglide.ssr =
	/** @type {any} */ (globalThis).__paraglide.ssr ?? {};

${injectCode("./get-locale.js")}

${injectCode("./get-text-direction.js")}

${injectCode("./set-locale.js")}

${injectCode("./get-url-origin.js")}

${injectCode("./check-locale.js")}

${injectCode("./extract-locale-from-request.js")}

${injectCode("./extract-locale-from-request-async.js")}

${injectCode("./extract-locale-from-cookie.js", {
        privateExports: ["clearLocaleCookieCache"],
    })}

${injectCode("./extract-locale-from-header.js")}

${injectCode("./extract-locale-from-navigator.js")}

${injectCode("./extract-locale-from-url.js")}

${injectCode("./localize-url.js")}

${injectCode("./should-redirect.js")}

${injectCode("./localize-href.js")}

${injectCode("./track-message-call.js")}

${injectCode("./generate-static-localized-urls.js")}

${injectCode("./strategy.js")}

${injectCode("./type-definitions.js").replace(`@typedef {string} Locale`, `@typedef {typeof locales[number]} Locale`)}
`;
    return code;
}
/**
 * Load a file from the current directory.
 *
 * Prunes the imports on top of the file as the runtime is
 * self-contained.
 *
 * @param {string} path
 * @param {{ privateExports?: string[] }} [options]
 * @returns {string}
 */
function injectCode(path, options) {
    const code = fs.readFileSync(new URL(path, import.meta.url), "utf-8");
    // Regex to match single-line and multi-line imports
    const importRegex = /import\s+[\s\S]*?from\s+['"][^'"]+['"]\s*;?/g;
    const sourceMapRegex = /\/\/# sourceMappingURL=.*$/gm;
    const blockSourceMapRegex = /\/\*# sourceMappingURL=.*?\*\//g;
    let injected = code
        .replace(importRegex, "")
        .replace(sourceMapRegex, "")
        .replace(blockSourceMapRegex, "")
        .trim();
    for (const exportName of options?.privateExports ?? []) {
        injected = injected.replace(new RegExp(`\\bexport\\s+function\\s+${exportName}\\b`, "g"), `function ${exportName}`);
    }
    return injected;
}
//# sourceMappingURL=create-runtime.js.map