/**
 * @file Docusaurus Documentation config.
 *
 * @import { UserThemeConfig, UserThemeConfigExtra } from "@goauthentik/docusaurus-config";
 * @import { AKReleasesPluginOptions } from "@goauthentik/docusaurus-theme/releases/common"
 * @import { AKRedirectsPluginOptions } from "@goauthentik/docusaurus-theme/redirects/plugin"
 * @import { Options as RedirectsPluginOptions } from "@docusaurus/plugin-client-redirects";
 * @import { NormalizedSidebar, NormalizedSidebarItemCategory, SidebarItemsGeneratorArgs } from "@docusaurus/plugin-content-docs/src/sidebars/types.ts";
 */

import { cp } from "node:fs/promises";
import { basename, resolve } from "node:path";
import { fileURLToPath } from "node:url";

import { createDocusaurusConfig } from "@goauthentik/docusaurus-config";
import {
    createAlgoliaConfig,
    createClassicPreset,
    extendConfig,
} from "@goauthentik/docusaurus-theme/config";
import { RewriteIndex } from "@goauthentik/docusaurus-theme/redirects";
import { parse } from "@goauthentik/docusaurus-theme/redirects/node";
import { prepareReleaseEnvironment } from "@goauthentik/docusaurus-theme/releases/node";
import { remarkLinkRewrite } from "@goauthentik/docusaurus-theme/remark";

const __dirname = fileURLToPath(new URL(".", import.meta.url));

const rootStaticDirectory = resolve(__dirname, "..", "static");
const packageStaticDirectory = resolve(__dirname, "static");
const authentikModulePath = resolve(__dirname, "..", "..");

const releaseEnvironment = prepareReleaseEnvironment();

//#region Copy static files

const files = [
    // ---
    resolve(authentikModulePath, "lifecycle/container/compose.yml"),
];

await Promise.all(
    files.map((file) => {
        const fileName = basename(file);
        const destPath = resolve(rootStaticDirectory, fileName);
        return cp(file, destPath, { recursive: true });
    }),
);

const redirectsFile = resolve(packageStaticDirectory, "_redirects");
const redirects = await parse(redirectsFile);
const redirectsIndex = new RewriteIndex(redirects);

//#endregion

/**
 * Generate Sidebar structure for CVEs. Items are grouped by year and sorted newest to old.
 *
 * @param {SidebarItemsGeneratorArgs} args
 * @returns {NormalizedSidebar}
 */
export function generateCVESidebar(args) {
    /** @type {{ [key: string]: NormalizedSidebarItemCategory}} */
    const yearCategories = {};
    args.docs
        .filter((item) => item.sourceDirName === "security/cves")
        .forEach((item) => {
            const matches = item.title.match(/CVE-(\d+)-/);
            if (!matches) {
                console.warn(`Could not extract year from CVE title: ${item.title}`);
                return;
            }
            const year = matches[1] || "";
            if (!Object.hasOwn(yearCategories, year)) {
                yearCategories[year] = {
                    type: "category",
                    label: year,
                    items: [],
                };
            }
            yearCategories[year]?.items.push({
                type: "doc",
                id: item.id,
            });
        });
    const categories = Object.values(yearCategories);
    categories.forEach((item) => {
        item.items.reverse();
    });
    categories.reverse();
    return categories;
}

//#region Configuration

export default createDocusaurusConfig(
    extendConfig({
        future: {
            faster: true,
        },
        clientModules: ["../docusaurus-theme/theme/utils/mermaid_icons.js"],
        url: "https://docs.goauthentik.io",
        //#region Preset

        presets: [
            createClassicPreset({
                pages: false,
                docs: {
                    sidebarItemsGenerator: async ({ defaultSidebarItemsGenerator, ...args }) => {
                        const sidebarItems = await defaultSidebarItemsGenerator(args);
                        if (args.item.dirName === "security/cves") {
                            return generateCVESidebar(args);
                        }
                        return sidebarItems;
                    },
                    exclude: [
                        /**
                         * Exclude previously generated API docs.
                         *
                         * @expires 2025-12-01
                         */
                        "**/developer-docs/api/reference/**",
                    ],
                    routeBasePath: "/",
                    path: ".",

                    sidebarPath: "./sidebar.mjs",
                    showLastUpdateTime: false,
                    editUrl: "https://github.com/goauthentik/authentik/edit/main/website/docs/",

                    //#region Docs Plugins

                    beforeDefaultRemarkPlugins: [
                        remarkLinkRewrite([
                            ["/api", "https://api.goauthentik.io"],
                            ["/integrations", "https://integrations.goauthentik.io"],
                        ]),
                    ],
                },
            }),
        ],

        //#endregion

        //#region Plugins

        plugins: [
            [
                "@goauthentik/docusaurus-theme/releases/plugin",
                /** @type {AKReleasesPluginOptions} */ ({
                    docsDirectory: __dirname,
                    environment: releaseEnvironment,
                }),
            ],

            // Inject redirects for later use during runtime,
            // such as navigating to non-existent page with the client-side router.

            [
                "@goauthentik/docusaurus-theme/redirects/plugin",
                /** @type {AKRedirectsPluginOptions} */ ({
                    redirects,
                }),
            ],

            // Create build-time redirects for later use in HTTP responses,
            // such as when navigating to a page for the first time.
            //
            // The existence of the _redirects file is also picked up by
            // Netlify's deployment, which will redirect to the correct URL, even
            // if the source is no longer present within the build output,
            // such as when a page is removed, renamed, or moved.
            [
                "@docusaurus/plugin-client-redirects",
                /** @type {RedirectsPluginOptions} */ ({
                    createRedirects(existingPath) {
                        const redirects = redirectsIndex.findAliases(existingPath);

                        return redirects;
                    },
                }),
            ],
        ],

        //#endregion

        //#region Theme

        themes: ["@goauthentik/docusaurus-theme", "@docusaurus/theme-mermaid"],

        themeConfig: /** @type {UserThemeConfig & UserThemeConfigExtra} */ ({
            algolia: createAlgoliaConfig({
                externalUrlRegex: /^(?:https?:\/\/)(?!docs\.goauthentik.io)/.source,
            }),

            image: "img/social.png",
            navbarReplacements: {
                DOCS_URL: "/",
            },
            navbar: {
                logo: {
                    alt: "authentik logo",
                    src: "img/icon_left_brand.svg",
                    href: "https://goauthentik.io/",
                    target: "_self",
                },
            },
        }),

        //#endregion
    }),
);
