defmodule TopSecret do
  def to_ast(string), do: Code.string_to_quoted!(string)

  def decode_secret_message_part({is_function?, _, arguments} = ast, acc)
      when is_function? in [:defp, :def] do
    {ast, [get_letters(arguments) | acc]}
  end

  def decode_secret_message_part(ast, acc), do: {ast, acc}

  defp get_letters([{:when, _, arguments} | _]), do: get_letters(arguments)

  defp get_letters([{name, _, arguments} | _]) when is_list(arguments),
    do: letters_from_name_and_arguments(name, arguments)

  defp get_letters([{name, _, arguments} | _]) when is_atom(arguments),
    do: letters_from_name_and_arguments(name, [])

  defp letters_from_name_and_arguments(name, arguments) do
    name
    |> Atom.to_string()
    |> String.slice(0, length(arguments))
  end

  def decode_secret_message(string) do
    {_ast, result} =
      string
      |> to_ast()
      |> Macro.prewalk([], &decode_secret_message_part/2)

    result
    |> Enum.reverse()
    |> Enum.join()
  end
end