#!/usr/bin/env -S node -r esbin
import { promises as fs } from "fs"
import { resolve } from "path"
import sass from "sass"
import { kebabCase } from "lodash"
import { tokenSource } from "~/shared/theme/tokens"

const trim = (s: string) => s.trim()

const [, outdir] = process.argv.slice(2)
// This file is used to `make theme`.
namespace primer {
  // https://github.com/primer/github-vscode-theme/commit/5f08d0cc4de8abc33e13c3f63fe92288824a11cf
  // prettier-ignore
  const classic = {
    black: "#1b1f23",
    white: "#fff",
    gray: ["#fafbfc", "#f6f8fa", "#e1e4e8", "#d1d5da", "#959da5", "#6a737d", "#586069", "#444d56", "#2f363d", "#24292e"],
    blue: ["#f1f8ff", "#dbedff", "#c8e1ff", "#79b8ff", "#2188ff", "#0366d6", "#005cc5", "#044289", "#032f62", "#05264c"],
    green: ["#f0fff4", "#dcffe4", "#bef5cb", "#85e89d", "#34d058", "#28a745", "#22863a", "#176f2c", "#165c26", "#144620"],
    yellow: ["#fffdef", "#fffbdd", "#fff5b1", "#ffea7f", "#ffdf5d", "#ffd33d", "#f9c513", "#dbab09", "#b08800", "#735c0f"],
    orange: ["#fff8f2", "#ffebda", "#ffd1ac", "#ffab70", "#fb8532", "#f66a0a", "#e36209", "#d15704", "#c24e00", "#a04100"],
    red: ["#ffeef0", "#ffdce0", "#fdaeb7", "#f97583", "#ea4a5a", "#d73a49", "#cb2431", "#b31d28", "#9e1c23", "#86181d"],
    purple: ["#f5f0ff", "#e6dcfd", "#d1bcf9", "#b392f0", "#8a63d2", "#6f42c1", "#5a32a3", "#4c2889", "#3a1d6e", "#29134e"],
    pink: ["#ffeef8", "#fedbf0", "#f9b3dd", "#f692ce", "#ec6cb9", "#ea4aaa", "#d03592", "#b93a86", "#99306f", "#6d224f"]
  };

  function addClassic(css: string, dark: boolean) {
    const r = (name: string, value?: string) =>
      (css = css.replace(
        RegExp(/(--color-NAME: )([^;]+);/.source.replace("NAME", name)),
        (_, name, originalValue) => `${name}${value ?? originalValue};`,
      ))

    r("canvas-default", dark ? "#1f2428" : undefined)
    return css
  }

  function sassCompile(code: string) {
    return sass.compileString(code, {
      loadPaths: [resolve(__dirname, "../node_modules")],
      style: "compressed",
    }).css
  }

  export async function main() {
    const outputDir = resolve(__dirname, "../dist/vendor/primer")
    await fs.mkdir(outputDir, { recursive: true })

    const themes = {
      dark: "dark-default",
      dark_colorblind: undefined,
      dark_dimmed: undefined,
      dark_high_contrast: undefined,
      dark_tritanopia: undefined,
      light: "light-default",
      light_colorblind: undefined,
      light_high_contrast: undefined,
      light_tritanopia: undefined,
    }

    const toRoot = (name: string, themeName = name) =>
      sassCompile(/* scss */ `
        @use "@primer/primitives/dist/scss/colors/_${name}.scss" as *;
        :root[data-theme="github-${themeName}"] {
          @include primer-colors-${name};
        }
      `)

    await Promise.all([
      ...Object.entries(themes).map(([source, name = source]) =>
        fs.writeFile(resolve(outputDir, `github-${name}.css`), toRoot(source, name)),
      ),
      fs.writeFile(
        resolve(outputDir, "github-dark.css"),
        addClassic(toRoot("dark"), true),
      ),
      fs.writeFile(
        resolve(outputDir, "github-light.css"),
        addClassic(toRoot("light"), false),
      ),
    ])
  }
}

async function tokens() {
  const declarations = Object.entries(tokenSource).map(([name, value]) => {
    const [light, dark] = value.trim().split(",").map(trim)
    return { name, light, dark }
  })

  await fs.writeFile(
    resolve(outdir, "tokens.generated.css"),
    [
      "body{",
      ...declarations.map(({ name, light }) => `--${kebabCase(name)}:${light};`),
      "}",
      "body.dark{",
      ...declarations.map(({ name, dark }) => `--${kebabCase(name)}:${dark};`),
      "}",
    ].join(""),
  )
}

async function main() {
  await tokens()
  await primer.main()
}

main()
