import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig } from "vitepress";
import { Command, commands } from "./cli_commands";
import {
  groupIconMdPlugin,
  groupIconVitePlugin,
} from "vitepress-plugin-group-icons";
import { tabsMarkdownPlugin } from "vitepress-plugin-tabs";
import { withMermaid } from "vitepress-plugin-mermaid";
import kdlGrammar from "./grammars/kdl.tmLanguage.json";
import miseTomlGrammar from "./grammars/mise-toml.tmLanguage.json";

const configDir = dirname(fileURLToPath(import.meta.url));
const cargoToml = readFileSync(resolve(configDir, "../../Cargo.toml"), "utf8");
const versionMatch = cargoToml.match(
  /^\[package\][\s\S]*?^\s*version\s*=\s*"([^"]+)"/m,
);
if (!versionMatch) {
  console.warn("Unable to find package version in Cargo.toml");
}
const latestVersion = versionMatch?.[1] ?? "0.0.0";

// https://vitepress.dev/reference/site-config
export default withMermaid(
  defineConfig({
    title: "mise-en-place",
    description: "mise-en-place documentation",
    lang: "en-US",
    lastUpdated: true,
    appearance: true,
    mermaid: {},
    sitemap: {
      hostname: "https://mise.jdx.dev",
    },
    themeConfig: {
      // https://vitepress.dev/reference/default-theme-config
      logo: { light: "/logo-light.svg", dark: "/logo-dark.svg" },
      outline: "deep",
      nav: [
        { text: "mise-versions", link: "https://mise-versions.jdx.dev/" },
        { text: "Dev Tools", link: "/dev-tools/" },
        { text: "Environments", link: "/environments/" },
        { text: "Tasks", link: "/tasks/" },
        {
          text: `v${latestVersion}`,
          link: "https://github.com/jdx/mise/releases",
        },
      ],
      sidebar: [
        {
          text: "Guides",
          items: [
            { text: "Demo", link: "/demo" },
            { text: "Getting Started", link: "/getting-started" },
            { text: "Walkthrough", link: "/walkthrough" },
            { text: "Installing mise", link: "/installing-mise" },
            { text: "IDE Integration", link: "/ide-integration" },
            { text: "Continuous Integration", link: "/continuous-integration" },
          ],
        },
        {
          text: "Configuration",
          items: [
            { text: "mise.toml", link: "/configuration" },
            { text: "Settings", link: "/configuration/settings" },
            {
              text: "Configuration Environments",
              link: "/configuration/environments",
            },
          ],
        },
        {
          text: "Dev Tools",
          items: [
            { text: "Dev Tools Overview", link: "/dev-tools/" },
            {
              text: "Comparison to asdf",
              link: "/dev-tools/comparison-to-asdf",
            },
            { text: "Shims", link: "/dev-tools/shims" },
            { text: "Tool Aliases", link: "/dev-tools/aliases" },
            { text: "Tool Stubs", link: "/dev-tools/tool-stubs" },
            { text: "Registry", link: "/registry" },
            { text: "GitHub Tokens", link: "/dev-tools/github-tokens" },
            { text: "mise.lock Lockfile", link: "/dev-tools/mise-lock" },
            { text: "Security", link: "/security" },
            { text: "OCI Images (experimental)", link: "/dev-tools/mise-oci" },
            { text: "Deps", link: "/dev-tools/deps" },
            {
              text: "Backend Architecture",
              link: "/dev-tools/backend_architecture",
            },
            {
              text: "Core tools",
              link: "/core-tools",
              collapsed: true,
              items: [
                { text: "Bun", link: "/lang/bun" },
                { text: "Deno", link: "/lang/deno" },
                { text: "Elixir", link: "/lang/elixir" },
                { text: "Erlang", link: "/lang/erlang" },
                { text: "Go", link: "/lang/go" },
                { text: "Java", link: "/lang/java" },
                { text: "Node.js", link: "/lang/node" },
                { text: "Python", link: "/lang/python" },
                { text: "Ruby", link: "/lang/ruby" },
                { text: "Rust", link: "/lang/rust" },
                { text: "Swift", link: "/lang/swift" },
                { text: "Zig", link: "/lang/zig" },
              ],
            },
            {
              text: "Backends",
              link: "/dev-tools/backends/",
              collapsed: true,
              items: [
                { text: "aqua", link: "/dev-tools/backends/aqua" },
                { text: "asdf", link: "/dev-tools/backends/asdf" },
                { text: "cargo", link: "/dev-tools/backends/cargo" },
                { text: "conda", link: "/dev-tools/backends/conda" },
                { text: "dotnet", link: "/dev-tools/backends/dotnet" },
                { text: "forgejo", link: "/dev-tools/backends/forgejo" },
                { text: "gem", link: "/dev-tools/backends/gem" },
                { text: "github", link: "/dev-tools/backends/github" },
                { text: "gitlab", link: "/dev-tools/backends/gitlab" },
                { text: "go", link: "/dev-tools/backends/go" },
                { text: "http", link: "/dev-tools/backends/http" },
                { text: "npm", link: "/dev-tools/backends/npm" },
                { text: "pipx", link: "/dev-tools/backends/pipx" },
                { text: "pkgx", link: "/dev-tools/backends/pkgx" },
                { text: "spm", link: "/dev-tools/backends/spm" },
                { text: "ubi", link: "/dev-tools/backends/ubi" },
                { text: "vfox", link: "/dev-tools/backends/vfox" },
              ],
            },
          ],
        },
        {
          text: "Bootstrap (experimental)",
          items: [
            { text: "Overview", link: "/bootstrap" },
            {
              text: "Bootstrap Packages",
              link: "/bootstrap/packages/",
              collapsed: true,
              items: [
                { text: "apk", link: "/bootstrap/packages/apk" },
                { text: "apt", link: "/bootstrap/packages/apt" },
                { text: "dnf", link: "/bootstrap/packages/dnf" },
                { text: "pacman", link: "/bootstrap/packages/pacman" },
                { text: "brew", link: "/bootstrap/packages/brew" },
              ],
            },
            {
              text: "Dotfiles",
              link: "/dotfiles",
            },
            {
              text: "macOS Defaults",
              link: "/bootstrap/macos-defaults",
            },
            {
              text: "launchd",
              link: "/bootstrap/launchd",
            },
            {
              text: "User Login Shell",
              link: "/bootstrap/user",
            },
          ],
        },
        {
          text: "Environments",
          items: [
            { text: "Environment Variables", link: "/environments/" },
            { text: "Shell Aliases", link: "/shell-aliases" },
            {
              text: "Secrets",
              link: "/environments/secrets/",
              collapsed: true,
              items: [
                { text: "sops", link: "/environments/secrets/sops" },
                { text: "age", link: "/environments/secrets/age" },
              ],
            },
            { text: "Hooks", link: "/hooks" },
            { text: "direnv", link: "/direnv" },
          ],
        },
        {
          text: "Tasks",
          items: [
            { text: "Task Overview", link: "/tasks/" },
            { text: "Task Architecture", link: "/tasks/architecture" },
            { text: "Running Tasks", link: "/tasks/running-tasks" },
            { text: "TOML Tasks", link: "/tasks/toml-tasks" },
            { text: "File Tasks", link: "/tasks/file-tasks" },
            { text: "Task Arguments", link: "/tasks/task-arguments" },
            { text: "Task Configuration", link: "/tasks/task-configuration" },
            { text: "Task Templates", link: "/tasks/templates" },
            { text: "Monorepo Tasks", link: "/tasks/monorepo" },
            { text: "Sandboxing", link: "/sandboxing" },
          ],
        },
        {
          text: "Plugins",
          items: [
            { text: "Plugin Overview", link: "/plugins" },
            { text: "Using Plugins", link: "/plugin-usage" },
            {
              text: "Backend Plugin Development",
              link: "/backend-plugin-development",
            },
            {
              text: "Tool Plugin Development",
              link: "/tool-plugin-development",
            },
            {
              text: "Environment Plugin Development",
              link: "/env-plugin-development",
            },
            { text: "Plugin Lua Modules", link: "/plugin-lua-modules" },
            { text: "Plugin Publishing", link: "/plugin-publishing" },
            { text: "asdf (Legacy) Plugins", link: "/asdf-legacy-plugins" },
          ],
        },
        {
          text: "About",
          items: [
            { text: "About mise", link: "/about" },
            { text: "Glossary", link: "/glossary" },
            { text: "FAQs", link: "/faq" },
            { text: "Troubleshooting", link: "/troubleshooting" },
            { text: "Tips & Tricks", link: "/tips-and-tricks" },
            {
              text: "Cookbook",
              link: "/mise-cookbook/",
              collapsed: true,
              items: [
                { text: "C++", link: "/mise-cookbook/cpp" },
                { text: "Docker", link: "/mise-cookbook/docker" },
                { text: "Node", link: "/mise-cookbook/nodejs" },
                { text: "Ruby", link: "/mise-cookbook/ruby" },
                { text: "Terraform", link: "/mise-cookbook/terraform" },
                { text: "Python", link: "/mise-cookbook/python" },
                { text: "Presets", link: "/mise-cookbook/presets" },
                { text: "Shell tricks", link: "/mise-cookbook/shell-tricks" },
              ],
            },
            { text: "Team", link: "/team" },
            { text: "Contributing", link: "/contributing" },
            { text: "External Resources", link: "/external-resources" },
          ],
        },
        {
          text: "Advanced",
          items: [
            { text: "Architecture", link: "/architecture" },
            { text: "Paranoid", link: "/paranoid" },
            { text: "Templates", link: "/templates" },
            { text: "URL Replacements", link: "/url-replacements" },
            { text: "Model Context Protocol", link: "/mcp" },
            { text: "Directory Structure", link: "/directories" },
            { text: "Cache Behavior", link: "/cache-behavior" },
          ],
        },
        {
          text: "CLI Reference",
          collapsed: true,
          items: [
            { text: "CLI Overview", link: "/cli/" },
            ...cliReference(commands),
          ],
        },
      ],

      socialLinks: [
        { icon: "github", link: "https://github.com/jdx/mise" },
        { icon: "discord", link: "https://discord.gg/UBa7pJUN7Z" },
      ],

      editLink: {
        pattern: "https://github.com/jdx/mise/edit/main/docs/:path",
      },
      search: {
        provider: "algolia",
        options: {
          indexName: "rtx",
          appId: "1452G4RPSJ",
          apiKey: "ad09b96a7d2a30eddc2771800da7a1cf",
          insights: true,
        },
      },
      footer: false,
      carbonAds: {
        code: "CWYIPKQN",
        placement: "misejdxdev",
      },
    },
    markdown: {
      languages: [
        // Load base languages needed for embedded support
        "toml",
        "shell",
        "bash",
        // TODO: Once Shiki bundles KDL (tracked in shikijs/textmate-grammars-themes),
        // we can import it from 'shiki/langs/kdl' instead of storing locally
        {
          ...kdlGrammar,
          name: "kdl",
          scopeName: "source.kdl",
        } as any,
        // Custom mise.toml grammar with embedded KDL (usage fields) and bash (run fields)
        {
          ...miseTomlGrammar,
          name: "mise-toml",
          aliases: ["mise.toml"],
          scopeName: "source.mise-toml",
        } as any,
      ],
      config(md) {
        md.use(groupIconMdPlugin);
        md.use(tabsMarkdownPlugin);
      },
    },
    vite: {
      build: {
        target: "es2022",
      },
      plugins: [
        groupIconVitePlugin({
          customIcon: {
            ".toml": "vscode-icons:file-type-toml",
            brew: "logos:homebrew",
            python: "logos:python",
            node: "logos:nodejs",
            ruby: "logos:ruby",
          },
        }),
      ],
    },
    head: [
      // Favicon
      ["link", { rel: "icon", href: "/favicon.ico", sizes: "any" }],
      [
        "link",
        {
          rel: "icon",
          href: "/favicon-16x16.png",
          type: "image/png",
          sizes: "16x16",
        },
      ],
      [
        "link",
        {
          rel: "icon",
          href: "/favicon-32x32.png",
          type: "image/png",
          sizes: "32x32",
        },
      ],
      ["link", { rel: "icon", href: "/favicon.svg", type: "image/svg+xml" }],
      [
        "link",
        {
          rel: "apple-touch-icon",
          href: "/apple-touch-icon.png",
          sizes: "180x180",
        },
      ],
      // Google Fonts
      [
        "link",
        {
          rel: "preconnect",
          href: "https://fonts.googleapis.com",
        },
      ],
      [
        "link",
        {
          rel: "preconnect",
          href: "https://fonts.gstatic.com",
          crossorigin: "",
        },
      ],
      [
        "link",
        {
          href: "https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=JetBrains+Mono:wght@400;500;600;700&display=swap",
          rel: "stylesheet",
        },
      ],
      [
        "script",
        {
          async: "",
          src: "https://www.googletagmanager.com/gtag/js?id=G-B69G389C8T",
        },
      ],
      [
        "script",
        {},
        `window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'G-B69G389C8T');`,
      ],
      // Open Graph
      ["meta", { property: "og:site_name", content: "mise-en-place" }],
      ["meta", { property: "og:type", content: "website" }],
      [
        "meta",
        {
          property: "og:image",
          content: "https://mise.jdx.dev/android-chrome-512x512.png",
        },
      ],
      ["meta", { name: "twitter:card", content: "summary" }],
      [
        "meta",
        {
          name: "twitter:image",
          content: "https://mise.jdx.dev/android-chrome-512x512.png",
        },
      ],
    ],
    transformPageData(pageData) {
      const canonicalUrl = `https://mise.jdx.dev/${pageData.relativePath}`
        .replace(/index\.md$/, "")
        .replace(/\.md$/, ".html");

      pageData.frontmatter.head ??= [];
      pageData.frontmatter.head.push([
        "link",
        { rel: "canonical", href: canonicalUrl },
      ]);
      pageData.frontmatter.head.push([
        "link",
        {
          rel: "sitemap",
          href: "https://mise.jdx.dev/sitemap.xml",
          type: "application/xml",
          title: "Sitemap",
        },
      ]);
    },
    transformHtml(code) {
      return code.replace(
        /<script id="check-dark-mode">/,
        '<script id="check-dark-mode" data-cfasync="false">',
      );
    },
  }),
);

function cliReference(commands: { [key: string]: Command }) {
  return Object.keys(commands)
    .map((name) => [name, commands[name]] as [string, Command])
    .filter(([_name, command]) => command.hide !== true)
    .map(([name, command]) => {
      const x: any = {
        text: `mise ${name}`,
        link: `/cli/${name}`,
      };
      if (command.subcommands) {
        x.collapsed = true;
        x.items = Object.keys(command.subcommands)
          .filter(
            (subcommand) => command.subcommands![subcommand].hide !== true,
          )
          .map((subcommand) => ({
            text: `mise ${name} ${subcommand}`,
            link: `/cli/${name}/${subcommand}`,
          }));
      }
      return x;
    });
}
