import glob from "fast-glob";
import path from "path";
import fs from "fs/promises";
import svgson from "svgson";
import { mkdir_to } from "../lib/builderator.js";

export const description = "Builds the sprite.svg sheet for icons based on the files in static/icons and what you use."


export const options = [
  ["--all-icons <glob>", "glob pattern with all .svg icons", "./static/icons/*.svg"],
  ["--sprite-sheet <filename>", "output sprite sheet with all icons", "./public/icon-sprites.svg"],
  ["--icons-index <filename>", "index.json file, be sure you know what you're doing", "./public/icons/index.json"],
  ["--prod-list <filename>", "JSON array file listing the icons to include for production"]
];

const load_svgs = async (svg_files) => {
  const results = [];
  // why use a for loop? because map don't async
  for(let fname of svg_files) {
    const name = path.basename(fname, ".svg");
    const contents = (await fs.readFile(fname)).toString();
    const parsed = await svgson.parse(contents);

    results.push({name, contents, parsed });
  }

  return results;
}

const symbolize = (svgs) => {
  const symbols = svgs.map(({name, parsed }) => {
    return {
      name: 'symbol',
      type: 'element',
      attributes: {
        id: name,
        viewBox: '0 0 24 24'
      },
      children: parsed.children,
    }
  });

  return symbols;
}

const sprite_sheet = async (symbols) => {
  const svg_doc = {
    name: 'svg',
    type: 'element',
    attributes: {
      xmlns: 'http://www.w3.org/2000/svg',
      version: '1.1',
    },
    children: [
      {
        name: 'defs',
        type: 'element',
        children: symbols,
      },
    ],
  }

  const xml_meta = `<?xml version="1.0" encoding="utf-8"?>\n`;
  const svg_xml = await svgson.stringify(svg_doc);

  return [xml_meta, svg_xml].join("");
}

export const main = async (opts) => {
  // list the svg files
  let svg_files;

  if(opts.prodList) {
    svg_files = JSON.parse(await fs.readFile(opts.prodList));
  } else {
    svg_files = glob.sync(opts.allIcons);
  }

  // load all of the icons from their svgs
  const svg_contents = await load_svgs(svg_files);

  // convert to linkable symbols
  const symbols = symbolize(svg_contents);

  // craft the svg doc
  const svg_doc = await sprite_sheet(symbols);

  // write out the sprite sheet
  await fs.writeFile(opts.spriteSheet, svg_doc);

  mkdir_to(opts.iconsIndex);

  // write out the json sprite list
  const sprite_list = svg_contents.map(({name}) => name);
  await fs.writeFile(opts.iconsIndex, JSON.stringify(sprite_list));

  if(!opts.dontExit) {
    process.exit(0);
  }
}
