defmodule MessageServer.MessageHandler do require Logger alias MessageServer.{ MessageRequest, RemoteClient, ServerRegistry, Storage } @spec handle_message(MessageRequest.t()) :: :ok | {:error, String.t()} def handle_message(%MessageRequest{from: from, to: to, message: message}) do with {:ok, from_server} <- extract_server_id(from), {:ok, to_server} <- extract_server_id(to), :ok <- validate_sender_ownership(from_server), :ok <- route_message(to_server, from, to, message) do Logger.info("Message routed successfully from #{from} to #{to}") :ok else {:error, reason} = error -> Logger.warning("Message routing failed: #{reason}") error end end @spec extract_server_id(String.t()) :: {:ok, String.t()} | {:error, String.t()} defp extract_server_id(user_id) do case String.split(user_id, "-", parts: 2) do [server_id, _user_part] -> {:ok, server_id} _ -> {:error, "Invalid user ID format: #{user_id}"} end end @spec validate_sender_ownership(String.t()) :: :ok | {:error, String.t()} defp validate_sender_ownership(sender_server) do local_server = ServerRegistry.get_server_id() if sender_server == local_server do :ok else {:error, "Cannot send messages on behalf of users from other servers"} end end @spec route_message(String.t(), String.t(), String.t(), String.t()) :: :ok | {:error, String.t()} defp route_message(to_server, from, to, message) do local_server = ServerRegistry.get_server_id() if to_server == local_server do handle_local_message(from, to, message) else handle_remote_message(to_server, from, to, message) end end @spec handle_local_message(String.t(), String.t(), String.t()) :: :ok | {:error, String.t()} defp handle_local_message(from, to, message) do Storage.append_message(to, from, message) end @spec handle_remote_message(String.t(), String.t(), String.t(), String.t()) :: :ok | {:error, String.t()} defp handle_remote_message(to_server, from, to, message) do payload = %MessageRequest{from: from, to: to, message: message} RemoteClient.send_message_to_server(to_server, payload) end end