#!/usr/bin/env bun
import { optimize } from "svgo";
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { resize } from "./js/resize.js";

const ROOT = import.meta.dirname,
  SVG_DIR = join(ROOT, "svg"),
  OUT_FILE = join(ROOT, "src/consts/svg.rs"),
  PLUGINS = [
    "preset-default",
    "removeDimensions",
    {
      name: "removeAttributesBySelector",
      params: {
        selector: "svg",
        attributes: ["width", "height", "xmlns"],
      },
    },
  ],
  svg_files = readdirSync(SVG_DIR).filter((f) => f.endsWith(".svg")),
  svg_sizes = new Map(),
  svgZip = (file) => {
    const path = join(SVG_DIR, file);
    resize(path);
    const data = readFileSync(path, "utf8");
    try {
      const result = optimize(data, { path, plugins: PLUGINS }),
        view_box = result.data.match(/viewBox="([^"]+)"/)?.[1];
      if (view_box) {
        const [, , w, h] = view_box.split(/\s+/).map(Number),
          size_key = w + "x" + h;
        if (!svg_sizes.has(size_key)) svg_sizes.set(size_key, []);
        svg_sizes.get(size_key).push(file);

        let inner_path = result.data.replace(/<svg[^>]*>|<\/svg>/g, "")
            .replace(/stroke="(?!none)[^"]+"/gi, 'stroke="inherit"')
            .replace(/fill="(?!none)[^"]+"/gi, 'fill="inherit"');

        return [view_box, w, h, inner_path, result.data];
      }
    } catch (e) {
      console.warn(`\n⚠️  WARN: Skipping invalid SVG file: ${file}\n    ${e.message.split('\n')[0]}`);
      return undefined;
    }
  },
  [svg_data] = await Promise.all([
    Promise.all(svg_files.sort().map(svgZip)),
  ]),
  header =
    "// This file is generated by svgCompress.js. DO NOT EDIT.\n" +
    "pub struct SvgIcon {\n" +
    "    pub view_box: &'static str,\n" +
    "    pub path: &'static str,\n" +
    "    pub raw: &'static str,\n" +
    "}\n\n" +
    "const fn icon(view_box: &'static str, path: &'static str, raw: &'static str) -> SvgIcon {\n" +
    "    SvgIcon { view_box, path, raw }\n" +
    "}\n\n" +
    "pub const SVGS: &[SvgIcon] = &[\n",
  body = svg_data
    .filter(Boolean)
    .map(
      (d) =>
        "    icon(" +
        JSON.stringify(d[0]) +
        ", " +
        JSON.stringify(d[3]) +
        ", " +
        JSON.stringify(d[4]) +
        ")",
    )
    .join(",\n"),
  footer = "\n];\n";

if (svg_sizes.size > 1) {
  console.warn("\n⚠️  WARN: Inconsistent SVG dimensions detected!");
  for (const [size, list] of svg_sizes) {
    console.warn(
      "   - " +
        size +
        ": " +
        list.length +
        " files (" +
        list.slice(0, 3).join(", ") +
        (list.length > 3 ? "..." : "") +
        ")",
    );
  }
}

writeFileSync(OUT_FILE, header + body + footer);
console.log(svg_data.length + " svg -> " + OUT_FILE);

