defmodule StaleMail do @moduledoc """ Stalemail is a persistent mailbox system used by Wideact. """ @doc """ Starts up the mailbox loop. """ def start() do loop(%{}) end @doc """ Loops through the received messages, parsing them and updating the mailbox state. """ defp loop(state) do newstate = receive do x -> parse(state, x) end loop(newstate) end @doc """ Parses the new message for updating the state. The :new_mailbox message connects a new client and creates a new mailbox if one is not already present. :new_mail is a check for new mail, which sends back the first of received messages for a given user. The :got_mail message is an acknowledgement that the user has received the first message, and it can be removed from the mailbox. The :pass_message message is the basic transfer mechanism in stalemail, passing the message to the receiver's mailbox (creating one in the process if not there). """ def parse(state, arg) do case arg do { :new_mailbox, zname, _sender } -> name = String.strip(zname) old = Map.has_key?(state, name) newstate = unless old do Map.put(state, name, []) else state end newstate { :new_mail, zname, sender } -> name = String.strip(zname) # TODO: asking about new mail if state |> Map.has_key?(name) do case state |> Map.get(name, []) do [ head | _tail ] -> send sender, head state _ -> state end end state { :got_mail, zname } -> name = String.strip(zname) # TODO: delete mail with given key if state |> Map.has_key?(name) do case state |> Map.get(name, []) do [ _ | tail ] -> state |> Map.put(name, tail) _ -> state end else state end { :pass_message, zreceiver, zmessage, zsender } -> receiver = String.strip(zreceiver) message = String.strip(zmessage) sender = String.strip(zsender) # TODO: passes message to mailbox of receiver if Map.has_key?(state, receiver) do list = state |> Map.get(receiver, []) state |> Map.put(receiver, list ++ [ { :received_message, sender, message } ]) else state |> Map.put(receiver, [ { :received_message, sender, message } ]) end end end end