defmodule Mix.Tasks.Phosphoricons.Build do
  # Builds a new lib/heroicons.ex with bundled icon set.
  @moduledoc false
  @shortdoc false
  use Mix.Task

  @target_file "lib/phosphoricons.ex"

  def run(_args) do
    vsn = Mix.Tasks.Phosphoricons.Update.vsn()
    svgs_path = Mix.Tasks.Phosphoricons.Update.svgs_path()

    bold = Path.wildcard(Path.join(svgs_path, "Bold/*.svg"))
    duotone = Path.wildcard(Path.join(svgs_path, "Duotone/*.svg"))
    fill = Path.wildcard(Path.join(svgs_path, "Fill/*.svg"))
    light = Path.wildcard(Path.join(svgs_path, "Light/*.svg"))
    regular = Path.wildcard(Path.join(svgs_path, "Regular/*.svg"))
    thin = Path.wildcard(Path.join(svgs_path, "Thin/*.svg"))

    ordered_icons = bold ++ duotone ++ fill ++ light ++ regular ++ thin

    icons = Enum.group_by(ordered_icons, &function_name(&1), &parse_svg(&1))

    Mix.Generator.copy_template(
      "assets/phosphoricons.exs",
      @target_file,
      %{icons: icons, vsn: vsn},
      force: true
    )

    Mix.Task.run("format")
  end

  defp function_name(file) do
    file
    |> Path.basename()
    |> Path.rootname()
    |> String.split("-")
    |> Enum.join("_")
    |> String.replace("_bold", "")
    |> String.replace("_duotone", "")
    |> String.replace("_fill", "")
    |> String.replace("_light", "")
    |> String.replace("_thin", "")
  end

  defp parse_svg(file) do
    for path <- file |> File.read!() |> String.replace("><", ">\n<") |> String.split("\n"),
        path = String.trim(path),
        supported_line?(path) do
      path |> String.replace(~r/ stroke="#0+"/, "")
    end
  end

  defp supported_line?(path) do
    ["path", "polyline", "circle", "line", "polygon", "ellipse", "rect"]
    |> Enum.any?(&String.starts_with?(path, "<#{&1}"))
  end
end
