defmodule DaProductApp.Switch do @moduledoc """ Main entry point for the ISO8583 switch system with proper architectural separation. This module coordinates two independent supervisors: - DeviceListenerSupervisor: Manages incoming Mercury device connections (port 5000) - NetworkSupervisor: Manages upstream network connections (VISA/MasterCard) Message Flow: Mercury Device → DeviceListenerSupervisor → Protocol.ex → Router.route() → NetworkSupervisor → Networks """ require Logger alias DaProductApp.MercuryISO8583.NetworkSupervisor alias DaProductApp.Switch.DeviceListenerSupervisor def start_listener(port \\ 5000) do Logger.info("Starting ISO8583 switch system on port #{port}") # Start both supervisors independently with :ok <- start_network_supervisor(), :ok <- start_device_listener_supervisor(port) do Logger.info("ISO8583 switch system started successfully") :ok else {:error, reason} -> Logger.error("Failed to start switch system: #{inspect(reason)}") {:error, reason} end end def stop_listener do Logger.info("Stopping ISO8583 switch system") # Stop both supervisors independently stop_device_listener_supervisor() stop_network_supervisor() :ok end def get_listener_info do device_listener_info = DeviceListenerSupervisor.get_status() network_info = NetworkSupervisor.get_status() %{ device_listener: device_listener_info, network_supervisor: network_info, message_flow: %{ incoming: "Mercury Device → DeviceListenerSupervisor (port 5000) → Protocol.ex", processing: "Protocol.ex → process_messages → Router.route()", outgoing: "Router.route() → NetworkSupervisor → Upstream Networks" } } end # Private functions defp start_network_supervisor do case NetworkSupervisor.start_link([]) do {:ok, _pid} -> Logger.info("NetworkSupervisor started successfully") # Start network connectors after supervisor initialization NetworkSupervisor.start_network_connectors() :ok {:error, {:already_started, _pid}} -> Logger.info("NetworkSupervisor already running") :ok {:error, reason} -> Logger.error("Failed to start NetworkSupervisor: #{inspect(reason)}") {:error, reason} end end defp start_device_listener_supervisor(port) do case DeviceListenerSupervisor.start_link([port: port]) do {:ok, _pid} -> Logger.info("DeviceListenerSupervisor started successfully on port #{port}") :ok {:error, {:already_started, _pid}} -> Logger.info("DeviceListenerSupervisor already running") :ok {:error, reason} -> Logger.error("Failed to start DeviceListenerSupervisor: #{inspect(reason)}") {:error, reason} end end defp stop_device_listener_supervisor do Logger.info("Stopping DeviceListenerSupervisor") case Process.whereis(DeviceListenerSupervisor) do nil -> :ok pid -> Process.exit(pid, :normal) :ok end end defp stop_network_supervisor do Logger.info("Stopping NetworkSupervisor") case Process.whereis(NetworkSupervisor) do nil -> :ok pid -> Process.exit(pid, :normal) :ok end end end