use std::convert::TryInto;
use std::env;
use std::num::Wrapping;

const REPLACEMENT_TABLE: [[u8; 16]; 8] = [
    [4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],
    [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],
    [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],
    [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],
    [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],
    [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],
    [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],
    [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12],
];
const KEYS: [u32; 8] = [
    0xE2C1_04F9,
    0xE41D_7CDE,
    0x7FE5_E857,
    0x0602_65B4,
    0x281C_CC85,
    0x2E2C_929A,
    0x4746_4503,
    0xE00_CE510,
];

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        let plain_text: Vec<u8> = vec![0x04, 0x3B, 0x04, 0x21, 0x04, 0x32, 0x04, 0x30];
        println!(
            "Before one step: {}\n",
            plain_text
                .iter()
                .cloned()
                .fold("".to_string(), |b, y| b + &format!("{:02X} ", y))
        );
        let encoded_text = main_step(plain_text, KEYS[0]);
        println!(
            "After one step: {}\n",
            encoded_text
                .iter()
                .cloned()
                .fold("".to_string(), |b, y| b + &format!("{:02X} ", y))
        );
    } else {
        let mut t = args[1].clone();