defmodule Mix.Tasks.Dog.Classes do
  @shortdoc "Lists all component classes"

  @moduledoc """
  Returns a list of all component classes.

  ## Usage

  List all component classes:

      mix dog.modifiers -m MyAppWeb.CoreComponents

  Write classes to file:

      mix dog.classes -m MyAppWeb.CoreComponents -o assets/classes.txt
  """

  use Mix.Task

  @parser_opts [
    aliases: [m: :module, o: :output],
    strict: [module: :string, output: :string]
  ]

  @requirements ["app.config"]

  @impl Mix.Task
  def run(args) do
    with {switches, [], []} <- OptionParser.parse(args, @parser_opts),
         {:ok, module} <- Keyword.fetch(switches, :module) do
      classes = list_classes(module)

      if path = Keyword.get(switches, :output) do
        file_header = file_header(module, path)
        File.write(path, file_header <> classes)
      else
        IO.puts(classes)
      end
    else
      _ ->
        IO.puts(@moduledoc)
    end
  end

  defp list_classes(module) do
    [module]
    |> Module.safe_concat()
    |> Doggo.classes()
    |> Enum.join("\n")
  end

  defp file_header(module, path) do
    """
    # This file was automatically generated by running:
    # mix dog.classes -m #{module} -o #{path}

    """
  end
end
