use std::io;
use rand::Rng;

use crate::genji;
use super::util;

fn readdata2(_api: &genji::Api, memsize: i16, dng_nr:i16)->bool
{
    // read 4 bytes ( contaning data length)
    let mut data_len_bytes = [0u8; 4];

    if 4 == _api.read_data2(&mut data_len_bytes, 0, 4, dng_nr ) {

        // convert 4 bytes to u32 
        let data_len = u32::from_ne_bytes(data_len_bytes);

        // when no length byte has been written, data_len is indefinite
        if data_len as i16 <= memsize  {

            // now we know the data length
            // allocate data length bytes
            let mut data = vec![0u8; data_len as usize];

            // read from offset 4
            if data_len as i16 == _api.read_data2(&mut data, 4, data_len as i16, dng_nr ) {
                println!("\n   Current Data:");

                //convert bytes to string and display
                println!("   {}",String::from_utf8(data).unwrap() );
                return true;
            }
            else{
                println!("\n   read_data1 error:{}", data_len);
            }
        }
        else{
            println!("   Data len is not set");
            return true;
        }
    }

    false
}

fn writedata2(_api: &genji::Api, data:&str, dng_nr:i16)->bool
{
    let data_len_bytes = (data.len() as i32).to_ne_bytes();
    let data_bytes     = data.as_bytes().to_vec();

    // data_len_bytes + data_bytes ( length = data.len() + 4)
    let write_bytes = [data_len_bytes.as_slice(), data_bytes.as_slice()].concat();

    let ret = _api.write_data2( &write_bytes, 0, write_bytes.len() as i16, dng_nr);
    if ret == write_bytes.len() as i16{
        println!("\n   ooooo Data written successfuuly ooooo");
        util::pause();
        return true;
    }
    else if ret == -9 {
        println!( "\n   xxxx Data2 is Locked xxx");
        return true;
    }

    false
}

pub fn data2_test( _api: &genji::Api, dng_nr:i16)->bool
{
    println!("   ******* Data2 Test ********");

    let memsize2 = _api.memsize2( dng_nr );
    println!("   MemSize2={}", memsize2);
    util::pause();

    if false == readdata2(_api, memsize2, dng_nr){
        return false;
    }

    println!("\n   Enter text to write to data2:");

    let mut input = String::new();

    // read from stdin
    io::stdin()
        .read_line(&mut input)
        .expect("failed to read from stdin");

    if input.trim().len() == 0 {
        println!("   Skipping data write");
        return true;
    }
   
    if writedata2(_api, input.trim(), dng_nr) == true {

        if false == readdata2(_api, memsize2, dng_nr){
            return false;
        }
        util::pause();
    }
    else{
        return false;
    }

    true
}

pub fn data1_test( _api: &genji::Api, dng_nr:i16)->bool
{
    println!("\n   ******* Data1 Test ********");

    let mut fields: [u32; 128] = [0; 128];

    if 128 != _api.read_data( &fields[..], 128, dng_nr) {
        println!( "   Failed to read field data:");
        return false;
    }
    println!( "   Current field data:");
    println!( "   {:?}", fields);

    println!( "\n  Set new values to fields 1-10");
   // init default radom generator
   let mut rng = rand::rng();
   for i in 0..10 {
        fields[i] = rng.random();  
        println!( "   field{}={}", i+1, fields[i]);
   }
   util::pause();

    println!( "\n   Trying to write new field data 1-10");
    if 10 != _api.write_dataex( &fields[0..10], 1,10,dng_nr) {

        return false;
    }
    println!( "   ---> Successful. Now try to read again");

    if 128 != _api.read_data( &fields[..], 128, dng_nr) {
        println!( "   Failed to read field data:");
        return false;
    }

    println!( "\n   Current field data:");
    println!( "   {:?}", fields);

    util::pause();
    println!("");
    true
}
