 defmodule Farmbot.Logger do
   @moduledoc """
     Logger backend for logging to the frontend and dumping to the API.
+    Takes messages that were logged useing Logger, if they can be
+    jsonified, adds them too a buffer, when that buffer hits a certain
+    size, it tries to dump the messages onto the API.
   """
   @rpc_transport Application.get_env(:json_rpc, :transport)
+  alias RPC.Spec.Notification, as: Notification
   use GenEvent
-  alias RPC.Spec.Notification, as: Notification
 
   # I SUCK
   def handle_event(thing, Farmbot.Logger), do: handle_event(thing, build_state)

    {:ok, unix}
  end
  defp parse_created_at({_,_}), do: {:ok, :os.system_time}

  @spec build_log(String.t, number, rpc_log_type, [channels], [integer])
  :: log_message
  defp build_log(message, created_at, type, channels, [x,y,z]) do
    %{message: message,
      created_at: created_at,
      channels: channels,
      meta: %{
        type: type,
        x: x,
        y: y,
        z: z }}
  end

  defp build_rpc(msg) do
    case Poison.encode(
      %Notification{
        id: nil,
        method: "log_message",
        params: [msg]})
    do
      {:ok, m} -> m
      _ -> IO.puts "error parsing #{inspect msg}"
    end
  end

  # Takes a list of rpc log messages
  defp build_rpc_dump(rpc_logs)
  when is_list(rpc_logs) do
    case Poison.encode(
      %Notification{
        id: nil,
        method: "log_dump",
        params:  rpc_logs })
    do
      {:ok, m} -> m
      _ -> IO.puts "error parsing #{inspect rpc_logs}"
    end
  end

  @type posting? :: boolean
  @spec build_state :: {[log_message], posting?}
  defp build_state, do: {[], false}
end

    pos = Farmbot.BotState.get_current_pos

    # take logger time stamp and spit out a unix timestamp for the javascripts.
    with {:ok, created_at} <- parse_created_at(timestamp),
         {:ok, log} <- build_log(message, created_at, type, channels, pos),
         {:ok, json} <- build_rpc(log),
         # ^ This will possible return nil if it cant create json.
         # it will silently be discarded.
         :ok <- @rpc_transport.emit(json),
         # make sure we add the non json version of the log message.
         do: dispatch({messages ++ [log], posting?})
    # if we got nil before, dont dispatch the new message into the buffer
    || dispatch({messages, posting?})
  end

  def handle_event(:flush, state) do
