use chisel_tuto::get_handle;
use cxxrtl::{CxxrtlHandle, CxxrtlSignal};
use std::env;

struct Blink {
    pub handle: CxxrtlHandle,
    pub clk: CxxrtlSignal<1>,
    pub led: CxxrtlSignal<1>,
    pub counter: CxxrtlSignal<12>,
}

impl Blink {
    fn new() -> Self {
        let lib = concat!(env!("OUT_DIR"), "/Example.so");
        let handle = get_handle(lib);
        let clk = handle.get("clock").unwrap().signal();
        let led = handle.get("io_led").unwrap().signal();
        let counter = handle.get("counter").unwrap().signal();
        Self {
            handle,
            clk,
            led,
            counter,
        }
    }

    fn step(&mut self) {
        self.handle.step()
    }
}

#[test]
fn test_example() {
    let mut blink = Blink::new();
    // blink.step();
    for cycle in 0..1000 {
        blink.clk.set(false);
        blink.step();
        let counter: u16 = blink.counter.get();
        assert_eq!(counter, cycle);
        blink.clk.set(true);
        blink.step();
        let counter: u16 = blink.counter.get();
        let count = cycle + 1;
        assert_eq!(counter, count);
        let curr_led: bool = blink.led.get();
        assert_eq!(curr_led, (count / 128) % 2 == 1);
    }
}