use std::error::Error;

use common::{
    base::NetService,
    impl_net_service,
    net::{tools::Packet, AServer, NetError, ServiceType},
    rpc_handlers, services,
};
use dashmap::DashMap;

use crate::{config::DispatchConfig, dispatch_service};
use paste::paste;

use super::gateserver_session::GateserverSession;

pub struct NetworkMgr {
    server: AServer,
    gateserver_sessions: DashMap<u32, GateserverSession>,
}

impl NetworkMgr {
    pub async fn new(config: &DispatchConfig) -> Result<Self, NetError> {
        let app_config = config
            .applications
            .get(&ServiceType::Dispatch)
            .unwrap()
            .iter()
            .find(|a| a.app_id == config.app_id)
            .expect("Failed to get applications.Dispatch entry");

        let server = AServer::bind(app_config.inner_ip.clone()).await?;

        Ok(Self {
            server,
            gateserver_sessions: DashMap::new(),
        })
    }

    pub async fn run(&self) {
        loop {
            let Ok(mut packets) = self.server.recv().await else {
                continue;
            };

            while let Some(packet) = packets.pop_front() {
                if let Err(err) = self.on_recv_to_svc(packet).await {
                    tracing::warn!("Packet processing error: {err}");
                }
            }
        }
    }

    rpc_handlers! {}

    services! {
        Gateserver;
    }

    pub async fn default_packet_process_func(&self, _: Packet) -> Result<(), Box<dyn Error>> {
        Ok(())
    }
}

impl_net_service!(Dispatch);
