use crate::common::define::*;
use crate::slave::slave_cmds::*;
use crate::common::define::{NATS_ACCOUNT, NATS_URL, NATS_PWD, TOPIC_ALL,SLAVE_ID};
use std::io::Write;
use std::io::stdout;
use crate::common::myfs::*;
use crate::slave::sync_cmd::other_sync_cmd;
use crate::slave::restart::cmd_restart;

pub fn dispatch() {
    std::thread::spawn(||{
        cmd_restart();
    });
    loop {
        match _dispatch() {
            Ok(()) =>print!("success one round\n"),
            Err(e) => {
                let res = format!("fail round{}\n", e);
                dbg!(res);
            }
        }
    }
}

fn _dispatch() -> anyhow::Result<()> {
    print!("slave begin to work\n");
    let nc = nats::ConnectionOptions::new()
        .with_name("remote shell")
        .with_user_pass(&NATS_ACCOUNT, &NATS_PWD)
        .connect(&NATS_URL)?;

    let sub = nc.subscribe(&TOPIC_ALL)?;
    for msg in sub.messages() {
        let from_host = std::str::from_utf8(&msg.data)?;
        // 如果rec，file已经是b64
        let ord: Order = serde_json::from_str(from_host)?;
        if ord.slave.clone() == SLAVE_ID.to_string() {
            stdout().flush()?;


            // 处理主体
            let ord_from_slave = reply_order(ord.clone());
            // 处理主体

            let feedback = serde_json::to_string(&ord_from_slave)?;
            dbg!("send res\n");
            msg.respond(feedback)?;
            dbg!("send over\n ");

        }
    }
    Ok(())
}

pub fn reply_order(ord: Order) -> Order {
    let mut slave1 = ord.clone();
    if let Err(e) = parse_input(&ord.req) {
        slave1.status = FAIL.to_owned();
        slave1.resp = format!("parse command error:{}", e);
        return slave1;
    }

    dbg!(&slave1.req);

    let (cmd, args) = parse_input(&slave1.req).unwrap();
    match cmd.as_str() {
        CMD_CD if args.len() == 1 => cmd_cd(&slave1),
        CMD_SEND => cmd_send(&slave1),
        CMD_REC => cmd_receive(&slave1),
        _ if slave1.wait => other_sync_cmd(&slave1),
        _ => {
            let a = other_async_cmd(&slave1);
            res2order(a, &slave1)
        }
    }
}
