use std::process::ExitCode;
use std::net::UdpSocket;
use std::thread;
use std::str;
use std::process;

mod genji;
pub mod test;
pub mod util;
pub mod data;
pub mod rsa;
pub mod xtea;
pub mod timer;


fn detect() {
    let s = UdpSocket::bind("127.0.0.1:37000");
    let socket;

    match s {
        Ok(_socket) => { socket = _socket },
        Err(_error) => {
            return;
        },
    };

    let mut buf = [0; 64];

    loop {
      match socket.recv_from(&mut buf) {
        Ok((buf_size, _)) => {
            let buf = &mut buf[..buf_size];
            let msg = str::from_utf8(&buf).unwrap();
            println!("{}" , msg);
            if msg == "removed"{
                 println!("   Removed! Program will exit\n");
                 process::exit(0);

            }
        },
        Err(_e) => {
          //println!("couldn't recieve request: {:?}", e);
        }
      }
    }
}


fn main() -> ExitCode {

    let _api = genji::Api::new(1234);

    _api.init();

    // run a thread to receive plug/unplug notification from Genji API
    thread::spawn(move || { detect() });

    // notify Genji of the waiting port for notification
    _api.register_genji_callback_port(37000);

    // detect to see how many Genji are connected
    let count = test::detect(&_api);

    if count < 1 {
        println!("No dongle found");
        return ExitCode::FAILURE;
    }

    // perform the test on each connected Genji in turn
    for dng_nr in 1..count+1{

        println!("<<<<<< Performing test on Genji No.{} >>>>>\n", dng_nr);
       
       if test::led_test( &_api, dng_nr) == false{
            break;
       }

       if test::rand_test(&_api, dng_nr) == false {
            break;
       }

       if  test::rtc_test(&_api, dng_nr) == false {
            break;
       }

       if data::data2_test(&_api, dng_nr) == false {
            break;
       }

       if data::data1_test(&_api, dng_nr) == false {
            break;
       }
    
       if rsa::rsa_encdec_test(&_api, dng_nr) == false {
            break;
       }

       if  rsa::rsa_sig_verify_test(&_api, dng_nr) == false{
           break;
       }

       if xtea::xtea_test(&_api,dng_nr) == false {
          break;
       }

        println!("")
    }

    _api.release();

    println!( "\n************************");
    println!("       Demo Over");
    println!( "************************\n\n");
    
    ExitCode::SUCCESS
}
