use prost::Message;
use proto::PacketHead;

use crate::{
    config::IpString,
    net::{AClient, NetError},
};

pub struct AServerSession {
    pub app_id: u32,
    client: AClient,
}

impl AServerSession {
    pub fn new(app_id: u32, service_ip: IpString, cur_app_id: u32) -> Self {
        let client = AClient::new(service_ip, cur_app_id);
        Self { app_id, client }
    }

    pub async fn send(&self, cmd_id: u16, proto: impl Message) -> Result<(), NetError> {
        self.client.send(cmd_id, PacketHead::default(), proto).await
    }
}

#[macro_export]
macro_rules! rpc_handlers {
    ($($name: ident;)*) => {
        pub async fn on_recv(&self, packet: ::common::net::tools::Packet) -> Result<(), Box<dyn ::std::error::Error>> {
            use ::proto::*;
            use ::prost::Message;
            use ::paste::paste;
            paste! {
                match packet.cmd_id {
                    $(
                        $name::CMD_ID => self.[<on_ $name:snake>](packet).await,
                    )*
                    _ => self.default_packet_process_func(packet).await
                }
            }
        }
    };
}
