use crate::common::define::*;
use reqwest::blocking::ClientBuilder;
use crate::common::define::{
    Order, CMD_RESTART,  REQ_DURATION, TOPIC_ALL, TOPIC_RESTART,  API_REQ
};
use crate::common::myfs::get_dot_env;
use crate::common::req_resp::Req;
lazy_static! {
    pub static ref NATS_URL:String =get_dot_env("NATS_URL");
    pub static ref NATS_ACCOUNT:String =get_dot_env("NATS_ACCOUNT");
    pub static ref NATS_PWD:String =get_dot_env("NATS_PWD");
    pub static ref SLAVE_ID:String=get_dot_env("SLAVE_ID");
}

pub struct Nat {}

pub struct Pass {}

// 必须要有&self，才可以Box<dyn Trans>
pub trait Trans {
    fn _send_order(&self,ord: &Order) -> anyhow::Result<Order>;
    fn _pub_restart(&self,slave: &str) -> anyhow::Result<()>;
}

impl Trans for Nat {
    fn _send_order(&self,ord: &Order) -> anyhow::Result<Order> {
        let nc = nats::ConnectionOptions::new()
            .with_name("remote shell")
            .with_user_pass(&NATS_ACCOUNT, &NATS_PWD)
            .connect(&NATS_URL)?;
        let input = serde_json::to_string(ord)?;
        let resp = nc.request_timeout(
            &TOPIC_ALL,
            input,
            std::time::Duration::from_secs(*REQ_DURATION + 5),
        )?;
        let str = std::str::from_utf8(&resp.data)?;
        let res = serde_json::from_str(str)?;
        Ok(res)
    }

    fn _pub_restart(&self,slave: &str) -> anyhow::Result<()> {
        let nc = nats::ConnectionOptions::new()
            .with_name("remote restart")
            .with_user_pass(&NATS_ACCOUNT, &NATS_PWD)
            .connect(&NATS_URL)?;
        let ord = Order::new_from_host(CMD_RESTART, &slave);
        let input = serde_json::to_string(&ord)?;
        nc.publish(&TOPIC_RESTART, input)?;
        Ok(())
    }
}



impl Trans for Pass {
    fn _send_order(&self,ord: &Order) -> anyhow::Result<Order> {

        let req=Req::init_from_order(TOPIC_ALL,ord);
        req.req_post_json()
    }

    fn _pub_restart(&self,slave: &str) -> anyhow::Result<()> {
        // pass 的重启命令和其他一个主题

        let ord = Order::new_from_host(CMD_RESTART, &slave);
        // 使用pass重启命令和其他走一个主题
        let req=Req::init_from_order(TOPIC_ALL,&ord);
        req.req_post_json()?;
        Ok(())
    }
}
