// use std::collections::{HashMap, HashSet};
use runner::common::*;

fn main() {
    let t1 = Task {
        id: "T1".to_string(),
        prio: 1,
        deadline: 100,
        inter_arrival: 100,
        trace: Trace {
            id: "T1".to_string(),
            start: 0,
            end: 10,
            inner: vec![],
        },
    };

    let t2 = Task {
        id: "T2".to_string(),
        prio: 2,
        deadline: 200,
        inter_arrival: 200,
        trace: Trace {
            id: "T2".to_string(),
            start: 0,
            end: 30,
            inner: vec![
                Trace {
                    id: "R1".to_string(),
                    start: 10,
                    end: 20,
                    inner: vec![Trace {
                        id: "R2".to_string(),
                        start: 12,
                        end: 16,
                        inner: vec![],
                    }],
                },
                Trace {
                    id: "R1".to_string(),
                    start: 22,
                    end: 28,
                    inner: vec![],
                },
            ],
        },
    };

    let t3 = Task {
        id: "T3".to_string(),
        prio: 3,
        deadline: 50,
        inter_arrival: 50,
        trace: Trace {
            id: "T3".to_string(),
            start: 0,
            end: 30,
            inner: vec![Trace {
                id: "R2".to_string(),
                start: 10,
                end: 20,
                inner: vec![],
            }],
        },
    };

	let debug = true;
	let advance = true;

    // builds a vector of tasks t1, t2, t3
	// in falling prio order IMPORTENT The order are used
    let mut tasks: Tasks = vec![t1, t2, t3];
//	tasks.sort_by(|a, b| (a.prio).partial_cmp(&b.prio).unwrap());
//	tasks.reverse();

    let (tp, rp, tr, a, dl) = pre_analysis(&tasks);
	
	let c = c_times(&tasks);
	let (l, l_tot) = load(&tasks, &c);
	let b = block(&tp, &rp, &tr);
	let i = interferens(&tp, &c, &a, &dl, advance);
	let r = response(&c, &b, &i);

	if debug{
    	println!("Debug data");
		println!("tasks {:?}", &tasks);
    	println!("tp: {:?}", tp);
    	println!("rp: {:?}", rp);
    	println!("tr: {:?}", tr);
		println!("DeadLine: {:?}", dl);
		println!("A: {:?}", a);
		println!("C(t): {:?}", c);
		println!("L(t): {:?}",l);
		println!("L(T): {:?}",l_tot);
		println!("B(t): {:?}", b);
		println!("I(t): {:?}", i);
		println!("R(t): {:?}", r);
		println!("");
	}

	analys_data(&tasks, l, &r, c, b, i, l_tot);
	test(dl, l_tot, &r);
}

// WARNIGN assums 0 overhead
fn test(dl: Data, l: f32,  r: &Data) {
	println!("TEST of real time critarias");
	if l <= 1.0 {
		println!("Load test SUCSES");
	} else {
		println!("Load test FAILD");
	}

	for (id, time) in dl {
		if time >= *r.get(&id).unwrap() {
			println!("Task {} respod in time: SUCSES", &id);
		} else {
			println!("Task {} respod to late: FAIL", &id);
		}
	}
	println!("");
}

fn analys_data(tasks: &Tasks, l: L, r: &Data, c: Data, b: Data, i: Data, load: f32){
	println!("The data for analyse");
	println!("Total load {}%", load);
	println!("ID | L | R | C | B | I | PRIO ");
	println!("------------------------------");
	for t in tasks {
		println!("{} | {} | {} | {} | {} | {} | {}", 
		t.id, l.get(&t.id).unwrap(), r.get(&t.id).unwrap(), c.get(&t.id).unwrap(), b.get(&t.id).unwrap(), i.get(&t.id).unwrap(), t.prio);
	println!("------------------------------");

	}
	println!("");
}
/*
TODO
for eatch task
c(t), r(t), b(t), i(t), l(t)

all
l_tot


HOW
c(t) = stop - start
l(t) = c(t) / a(t)
r(t) = c(t) + b(t) + i(t)

b(t) = sum {for eatch max(R) where pi(r) > p(t)
i(t) = sum { (ph(h)/bp(t) * c(h)) where p(h) > p(t)


ip: {"R1": 2, "T2": 2, "R2": 3, "T1": 1, "T3": 3}
tr: {"T2": {"R1", "R2"}, "T3": {"R2"}}

*/