use std::env;
use std::collections::HashMap;

#[tokio::main]
pub async fn main() {
    let a = match env::args().nth(1) {
        Some(a) => a, None => {
            println!("[ERROR] No args");
            return;
        },
    };
    let mut map: HashMap<_, Box<dyn Call>> = HashMap::new();
    map.insert("1", Box::new(T001{}) );
    map.insert("2", Box::new(T002{}) );

    let c = match map.get(a.as_str()) {
        Some(c) => c, None => {
            println!("[ERROR] Cannot find {}", a);
            return;
        },
    };

    match c.call().await {
        Ok(_) => println!("[OK] Call fn ok: {}", a),
        Err(err) => println!("[ERROR] Call fn error: {}, message: {}", a, err),
    }
}

#[async_trait::async_trait]
trait Call {
    async fn call(&self) -> Result<(), Box<dyn std::error::Error>>;
}

struct T001();
#[async_trait::async_trait]
impl Call for T001 {
    async fn call(&self) -> Result<(), Box<dyn std::error::Error>> {
        let ip = reqwest::get("https://hatter.ink/ip/ip.jsonp").await?.text().await?;
        println!("{}", ip);
        Ok(())
    }
}

struct T002();
#[async_trait::async_trait]
impl Call for T002 {
    async fn call(&self) -> Result<(), Box<dyn std::error::Error>> {
        // let resp = reqwest::get("https://hatter.ink/ip/ip.jsonp").await?;
        // use std::io::Read;

        // let mut buff = [0_u8; 1024];

        // loop {
        //     match resp.read(buff) {
        //         Ok(_) => (),
        //         Err(_) => (),
        //     }
        // }
        
        println!("Hello World 2");
        Ok(())
    }
}
