 defmodule HELL.UUID do
+  @moduledoc """
+  Generates UUID v4 with custom format.
+  The UUID follows v4 style, but is not compliant due to the custom header.
+  The custom header is included to help with the debug process.
+  """
 
+  # allowed hex characters, hex is case sensitive, always use lowercased letters
   @hex_chars ?0..9
     |> Enum.to_list()
     |> Kernel.++(Enum.to_list(?a..?f))
     |> Enum.map(&List.wrap/1)
     |> Enum.map(&to_string/1)
 
-  def create(domain_name, opts \\ []) do
-    head = header(domain_name, opts)
+  @doc """
+  Generates UUID with given `domain`, `meta1` and `meta2`.
+  Domain is must always use two characters, metas must use just a single.
+  The default value for metas is `0`.
+  """
+  def create(domain, opts \\ []) do
+    head = header(domain, opts)
     if head, do: merge_header(head), else: nil
   end
 
-  def merge_header(head),
-    do: if head, do: merge(UUID.uuid4(), head), else: nil
-
+  @doc """
+  Generates a valid header with given `domain`, `meta1` and `meta2`.
+  Follow the same format rules from create.
+  Useful for caching headers on module attributes, merge the header into an UUID later using
+  `merge_header/1`.
+  """
   def header(domain, opts \\ []) do
     meta1 = Keyword.get(opts, :meta1, "0")
     meta2 = Keyword.get(opts, :meta2, "0")

  defp valid_meta?(_),
    do: false

  for x <- @hex_chars, y <- @hex_chars do
    defp valid_domain?("#{unquote(x)}#{unquote(y)}"),
      do: true

  defp merge(uuid, "", acc),
    do: acc <> uuid

  @docp """
  Validates meta attributes.
  """
  for x <- @hex_chars do
    defp valid_meta?("#{unquote(x)}"),
      do: true
