#![allow(non_snake_case)]
#![allow(non_camel_case_types)] 
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]

use std::{
    time
};
use lwleen_rpc::{ serde_json,futures::{self,Future, stream::{Stream,FusedStream},StreamExt, FutureExt }};
use clap;
use shlex;
use lwleen::{
    prelude::*,
    lwleen_rpc::{ Demo_模块特征 },
};
use regex_lite::Regex;
use libc;



#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
fn main() -> anyhow_Result<()>{
    
    let 启动参数数组: Vec<String> = std::env::args().collect();
    if  启动参数数组.len() >=2{       // 0 是执行文件本身  =======> 执行函数  1 是函数名 
        
        block_on_lite(async move{
            let 信令路由 = 信令路由::default();
            let 参数数组 = 启动参数数组[1..].to_vec();  
            
            match app_exec文本信令(&信令路由, 参数数组).await{
                Ok(输出) => {  println!("_JSON标志_{输出}")  }
                Err(err) => {  eprintln!("!运行错误:{err}")  ;std::process::exit(1);  }     //这里函数执行中的错误， 不是stderr 
            };
        });
    }else{
        let 信令路由c1 =  信令路由::default();
        
        // 自定义服务端
        // use async_std;
        // let 信令路由c1 = 信令路由::new(rpc类型::none自定义);
        // let 信令路由c2 = 信令路由c1.clone();
        // std::thread::spawn(move||{
        //     async_std::task::block_on(async move{
        //         while let Ok(msg) = 信令路由c2.core_chan接收通道().recv().await{
        //              async_std::task::spawn( 信令路由::core_信令包消费_执行(&信令路由c2, msg) );
        //         }
        //     });
        // });


        let (信令路由c1,信令路由c2,信令路由c3) = (信令路由c1.clone(),信令路由c1.clone(),信令路由c1.clone());
        //作为独立进程运行
        #[derive(Debug,Default,Clone, serde::Deserialize, serde::Serialize)]
        struct 返回结果{ 事件戳:u64, 状态:bool, 结果:String }
        #[derive(Debug,Default,Clone, serde::Deserialize, serde::Serialize)]
        struct 外部指令{  事件戳:u64, 参数数组:Vec<String>  }
       
        let 异步stdin通道 = 异步读取_stdin();
 

        // - block_on_lite
        信令路由c1.spawn异步任务(async move{
            let 派发新任务 = |msg:外部指令|{
                let 信令路由clone = 信令路由c2.clone();
                信令路由c2.spawn异步任务(async move{
                    let 事件戳 = msg.事件戳;  
                    let 函数名 = if msg.参数数组.len()>0 {msg.参数数组[0].clone()} else{ "".to_string()};
           
                    let now = std::time::Instant::now();
                    let 结果 =  app_exec文本信令(&信令路由clone, msg.参数数组).await;
                    eprintln!("\x1b[0;32m{事件戳:<5} {:>25}  ->  {函数名}\x1b[0m", 信令路由::fn_时间to时间字符串(now,false) );
                    
                    let out = match 结果{
                        Ok(输出)  =>{ 返回结果{ 事件戳, 状态:true, 结果: format!("_JSON标志_{输出}") }   }  
                        Err(err)  =>{ 返回结果{ 事件戳, 状态:false, 结果: format!("rust任务 {} > {} > {}",事件戳,函数名,err) }  }
                    };
                    println!("_开🌷_{}_🍊束_\n", serde_json::json!(&out).to_string().trim() );
                });
            };
            
            while let Ok(stdin文本) = 异步stdin通道.recv().await { 
                let mut 解码成功 = false;
                //模式1  直接匹配字符串
                for 文本 in 解码文本信令(&stdin文本){
                    if let Ok(msg) =  serde_json::from_str::<外部指令>(&文本){
                        派发新任务(msg); 解码成功 = true;
                    }
                }
                //模式2  clap 菜单
                if !解码成功 && let Ok(参数数组) = cli解码信令(&信令路由c2,&stdin文本){
                    派发新任务(外部指令{事件戳:0,参数数组});
                }
            }
            信令路由c2.emit退出主线程(90,None); 
        });
        
        
        eprintln!("版    本：{}",env!("CARGO_PKG_VERSION"));
        eprintln!("作    者：{}",env!("CARGO_PKG_AUTHORS"));
        eprintln!("主    页：{}",env!("CARGO_PKG_HOMEPAGE"));
        eprintln!("路由类型：\x1b[1;34m{}\x1b[0m",信令路由c3.core_ref服务端类型());
        eprintln!("打包时间：{}",env!("BUILD_TIME"));
        eprintln!("\x1b[1;32m文件所在：\x1b[0m{:?}",std::env::current_exe().unwrap_or_default());
        
        eprintln!("\n---->💖>  rust线程_交互模式  >💖>----\n");
        
        cfg_if! {
            if #[cfg(all(feature = "mod_dioxus"))]{
                信令路由c3.on阻塞_主线程窗口_dioxus().ok();
            }
            else if #[cfg(all(feature = "mod_slint"))]{
                信令路由c3.on阻塞_主线程窗口_slint().ok();
            }
            else{
                信令路由c3.on阻塞_主线程().ok();
            }
        }
        eprintln!("\n---->🍁>  rust线程_交互模式  退出 >🍁>----");
    }
    Ok(()) 
}








//------ 文本指令解析 --------
use clap::{arg,Arg, Command, error::ErrorKind};
fn cli解码信令(信令路由ref:&信令路由, 字符串:impl AsRef<str>)->anyhow_Result<Vec<String>>{
    let args = shlex::split(字符串.as_ref()).ok_or("error: Invalid quoting").map_err(|err|{ anyhow_err!(err) })?;
    let matches = cli().try_get_matches_from(args);
    
    if let Err(ref err) = matches{   let _ = err.print(); eprintln!("");  };  //需要手动打印help
    match matches?.subcommand() {
        Some(("t", _matches))      => {   信令路由ref.demo范例("用户指令 t").block阻塞完成().ok();     }
        Some(("tt", sub_matches))   => {  eprintln!("\n{:#?}\n",信令路由ref.rpc信令路由_状态());  return Ok(vec!["rpc信令路由_心跳".to_string()]);  }
        Some(("a", sub_matches))   => {
            match sub_matches.subcommand(){
                Some(("home",sub_matches))=>{ return Ok(vec!["home".into()]); }
                _=>{
                    let 函数名 = sub_matches.get_one::<String>("函数名").map(|arg|arg.to_owned()).unwrap_or_default().to_string();
                    if 函数名==""{ eprintln!("\x1b[1m需要参数, 例如: a  home|os|cpu|mem|net|ip|port|smb|term|file|dir|ui_slint\x1b[0m"); }
                    else{
                        let mut 数组 = sub_matches.get_many::<String>("参数数组").into_iter().flatten().map(|arg|arg.to_owned()).collect::<Vec<_>>();
                        数组.insert(0, 函数名);
                        return Ok(数组);
                    }
                }
            }
        }
        Some(("test", sub_matches)) => {
            println!("\n定时器:");
            let 定时器 = 信令路由ref.Interval(300, |定时器|{  
                println!("✅-> Interval循环 200ms  执行次数:{}",定时器.get_执行次数());
                if 定时器.get_执行次数() >=2{ 定时器.stop(); }
            });
            信令路由ref.Timeout(1000, move|_|{  定时器.start(); println!("⚡-> Timeout结束");    });
        }
        Some(("quit", _matches))    => {
            print!("正在退出 ...\n");
            std::process::exit(1);
            
            // std::io::stdout().flush().map_err(|err|{ anyhow_err!(err) })?;
            // return Err(anyhow_err!("quit"));
        }
        Some((name, sub_matches)) => {
            let args = sub_matches 
                .get_many::<String>("参数数组").into_iter().flatten().map(|arg|arg.to_owned()).collect::<Vec<_>>();
            
            cli().打印指令();
            eprintln!("调用 {name:?} -> {args:?}");
        }
        None =>{ unreachable!("错误调用 unreachable")  }
    }
    Err(anyhow_err!("匹配失败"))
}

fn cli() -> clap::Command {
    // strip out usage
    const PARSER_TEMPLATE: &str = "\
        {all-args}
    ";
    // strip out name/version
    const APPLET_TEMPLATE: &str = "\
        {name} {version}\n\
        {about-with-newline}\n\
        {usage-heading}\n    {usage}\n\
        \n\
        {all-args}{after-help}\
    ";
    
    clap::Command::new("顶层指令")
        .bin_name("lwleen_bin")
        .multicall(true)
        .arg_required_else_help(true)
        .subcommand_required(true)
        // .subcommand_value_name("APPLET")
        // .subcommand_help_heading("APPLETS")
        .help_template(PARSER_TEMPLATE)
        .subcommand( clap::Command::new("a")
                .about("执行函数, 例如: a  home|os|cpu|mem|net|http|web|ip|port|smb|term|file|dir|ui_slint")
                .subcommand(
                    clap::Command::new("home")
                                .about("系统基础目录")
                )
                .arg(
                    Arg::new("函数名")
                        .value_parser(clap::value_parser!(String))
                        // .num_args(0)       0.. 匹配多个 
                        // .required(true)
                )
                .arg(
                    Arg::new("参数数组")
                        .action(clap::ArgAction::Append)
                        .value_parser(clap::value_parser!(String))
                        .help("所有未识别的参数将被传递给脚本")
                        .trailing_var_arg(true)   
                )
        )
        .subcommand( clap::Command::new("t")
                        .about("测试  ->  rpc信令路由_心跳")
        )
        .subcommand( clap::Command::new("tt")
                .alias("rpc")
                .alias("info")
                .about("rpc信令路由 状态")
                .help_template(APPLET_TEMPLATE)
        )
        .subcommand( clap::Command::new("test")
                .about("测试 定时器")
                .arg(
                    Arg::new("参数数组")
                        .value_parser(clap::value_parser!(String))
                        .num_args(0..)
                )
        )
        // .subcommand( clap::Command::new("run")
        //         .about("另一种执行函数, 例如: run dir")
        //         .arg_required_else_help(true)
        //         .arg(arg!(<参数数组> ... "这里是所有参数").value_parser(clap::value_parser!(String)))
        // )

        .subcommand( clap::Command::new("quit")
                .alias("exit")
                .about("退出应用")
                .help_template(APPLET_TEMPLATE)
        )

}


trait 打印 {  fn 打印指令(&mut self);  }
impl 打印 for clap::Command{
    fn 打印指令(&mut self){
        if let Some(cmd) = self.get_subcommands_mut().find(|c| c.get_name() == "go") {
            eprintln!("About for 'go': {}", cmd.get_about().unwrap_or_default());
            eprintln!("\nFull help for 'create':\n{}", cmd.render_help());  // 打印完整帮助信息
        }
    }
}






pub fn 异步读取_stdin() ->  async_Receiver<String> {
    // let stdin = async_io::Async::new(std::io::stdin());
    
    use std::io::BufRead;
    let (tx, rx) =  async_unbounded::<String>();
    let stdin = std::io::BufReader::new(std::io::stdin());
    let 记录进程ppid = unsafe { libc::getppid() };
    std::thread::spawn(move ||{
        let mut lines = stdin.lines();
        loop {
            let 进程ppid = unsafe { libc::getppid() };   //避免成为孤儿进程
            if 进程ppid != 记录进程ppid{ break; }
            
            if let Some(Ok(line)) = lines.next(){  tx.force_send(line).ok(); }
        }
        信令路由::fn_立即退出当前进程(90);
    });
    rx
}


pub fn 解码文本信令(字符串:impl AsRef<str>)->Vec<String>{
    let mut 最终文本数组:Vec<String> = Vec::new();
    let 指令文本 = 字符串.as_ref();
    for 匹配 in Regex::new(r"_开🌷_[\d\D]+?_🍊束_").unwrap().find_iter(指令文本.trim()){
        let 文本 = 匹配.as_str().trim_start_matches("_开🌷_").trim_end_matches("_🍊束_");
        最终文本数组.push(文本.to_string());
    }
    最终文本数组
}



use std::io::Write;
//阻塞等待 用户按下enter才会触发一次
pub fn loop_stdin阻塞等待用户输入<F>( mut stdin循环回调:F) ->anyhow_Result<()>
where F: FnMut(String)->anyhow_Result<()>,
{
    use std::io::{BufRead,Read};
    let 记录进程ppid = unsafe { libc::getppid() };
    loop{
        let 进程ppid = unsafe { libc::getppid() };   //避免成为孤儿进程
        if 进程ppid != 记录进程ppid{ return Err(anyhow_err!("父进程已经退出"));  }

        // std::io::stdout().flush().map_err(|err| anyhow_err!("{err}")).ok();
        let buffer;
        {
            let mut stdin = std::io::stdin().lock();   //会阻塞进程等待消息
            buffer = stdin.fill_buf()?.to_owned();
            stdin.consume(buffer.len());
        }
        let stdin文本 = String::from_utf8(buffer)?;  
        stdin循环回调(stdin文本)?;
    };
}


/*
    let stdin = async_std::io::stdin();
    let reader = async_std::io::BufReader::new(stdin);
    let mut async_lines = reader.lines();

    ok_stdin = async_lines.next().fuse() =>{ stdin接收文本(&mut 并行任务 , ok_stdin);   }
*/