Documentation
#![allow(dead_code, async_fn_in_trait)]
pub mod base_config;
pub mod card_service;
pub mod config;
pub mod controller;
pub mod database;
pub mod packers;
pub mod peer;
pub mod robot_service;
pub mod services;
pub mod static_def;
pub mod time;
pub mod timer;

pub use clickhouse;

use anyhow::{anyhow, Result};
use futures::future::BoxFuture;
use netxserver::prelude::NetXServer;
use once_cell::sync::OnceCell;
use std::sync::Arc;

use crate::controller::{ImplCreateProxyController, ProxyController};
use crate::services::{ILinkPeerManager, IProxyService};
use crate::static_def::{BASE_CONFIG, MASTER_SERVICE, PROXY, TIMER_MANAGER};

/// 静态安装配置
pub static GAME: OnceCell<Game> = OnceCell::new();

/// 数据处理函数指针
/// 用于外导入
pub type Func =
    for<'a> fn(&'a ProxyController, i32, u64, Vec<u8>) -> BoxFuture<'a, Result<Vec<u8>>>;

/// 基本安装
pub struct Game {
    pub peers: Arc<dyn ILinkPeerManager>,
    pub func: Func,
}

impl Game {
    /// 安装服务
    pub async fn init(
        peers: Arc<dyn ILinkPeerManager>,
        func: Func,
    ) -> Result<NetXServer<ImplCreateProxyController>> {
        #[cfg(feature = "remote_load")]
        {
            use crate::static_def::{load_base_config, load_config, BASE_CONFIG_CELL, CONFIG_CELL};
            let config = load_config().await?;
            CONFIG_CELL.get_or_init(move || config);

            let base_config = load_base_config().await?;
            BASE_CONFIG_CELL.get_or_init(move || base_config);
        }

        GAME.set(Self { peers, func })
            .map_err(|_| anyhow!("not install game"))?;

        if let Err(err) = MASTER_SERVICE.init(BASE_CONFIG.base.server_id).await {
            log::error!("connect master server error:{}", err);
        }

        //新建服务器,需要设置和接口实现
        let server =
            NetXServer::new(BASE_CONFIG.proxy_listen.clone(), ImplCreateProxyController).await;
        PROXY
            .set_manager(server.get_token_manager().upgrade().unwrap())
            .await;

        // 开始Timer
        TIMER_MANAGER.start();

        // 开始服务器,堵塞模式
        log::info!("starting ns game service:{}", BASE_CONFIG.base.server_id);
        Ok(server)
    }
}