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


fn xtea_encrypt( data: &mut [u32], key:&[u32])->i16{
    let mut sum:u32 = 0;
    let delta:u32 = 0x9E3779B9;

//      for cnt = 32; cnt > 0; cnt-- {
    for _ in (1..=32).rev() {
        data[0] += ((data[1]<<4 ^ data[1]>>5) + data[1]) ^ (sum + key[(sum&3) as usize]);
        sum += delta;
        data[1] += ((data[0]<<4 ^ data[0]>>5) + data[0]) ^ (sum + key[(sum>>11&3) as usize]);
    }
    
    0
}

fn xtea_decrypt( data: &mut [u32], key:&[u32])->i16{

    let mut sum:u32 = 0xC6EF3720;
    let delta:u32 = 0x9E3779B9;

//      for cnt = 32; cnt > 0; cnt-- {
    for _ in (1..=32).rev() {
        data[1] -= ((data[0]<<4 ^ data[0]>>5) + data[0]) ^ (sum + key[(sum>>11&3) as usize]);
        sum -= delta;
        data[0] -= ((data[1]<<4 ^ data[1]>>5) + data[1]) ^ (sum + key[(sum&3) as usize]);
    }
    
    0
}

pub fn xtea_test(_api: &genji::Api, dng_nr:i16)->bool
{
    println!("\n   ******* XTEA test*******");

    let key = [1111122222,1111133333,2222244444,2222255555];

    let mut data =[ 
         [1234567890, 1234567890],
         [2233445566, 1122445577],
         [1468205773, 0934113682],
         [3942612857, 2557492693],
         [ 2670314019, 1725837151] ];

    println!("\n   ... encrypt/decrypt by Genji");
    
    if _api.write_key( &key, dng_nr) < 1 {
        println!( "   Failed to write XTEA key");
        return false;
    }

    println!( "       using key    {:?} hex {:x?}\n", key, key);

    let mut timer = timer::GenjiTimer {  mode:0,  api: _api, started:false, counter: 0};

    timer.start(dng_nr);

    for row in &mut data  {

        println!( "   Plain    {:?} hex {:x?}", row, row);

        if _api.encrypt_data( row , dng_nr ) < 1 {
            println!( "   Failed to encrypt");
            return false;
        }
        println!("   Encrypted {:?} hex {:x?}", row, row);

        if _api.decrypt_data( row , dng_nr) < 1 {
            println!( "   Failed to decrypt");
            return false;
        }
        println!("   Decrypted {:?} hex {:x?}", row, row);

        println!("")
    }

    timer.stop(dng_nr);
    println!( "   Processing time: {} msec",timer.counter);
    util::pause();

    println!("\n   ... encrypt/decrypt by algorithm");

    println!( "       using key    {:?} hex {:x?}\n", key, key);

    timer.start(dng_nr);

    for row in &mut data  {

        println!( "   Plain    {:?} hex {:x?}", row, row);

        xtea_encrypt( row, &key);
        println!("   Encrypted {:?} hex {:x?}", row, row);

        xtea_decrypt( row, &key);
        println!("   Decrypted {:?} hex {:x?}", row,row);

        println!("")
    }

    timer.stop(dng_nr);
    println!( "Processing time: {} msec",timer.counter);
    util::pause();

    true
}