// Libtock regression tests to be used with real hardware.
// Requires P0.03 and P0.04 to be connected (on a nRF52 DK).

#![no_std]

extern crate alloc;

use alloc::string::String;
use core::fmt::Write;
use core::future::Future;
use core::mem;
use core::pin::Pin;
use core::task::Context;
use core::task::Poll;
use libtock::console::Console;
use libtock::console::ConsoleDriver;
use libtock::gpio::GpioDriverFactory;
use libtock::gpio::GpioState;
use libtock::gpio::ResistorMode;
use libtock::result::TockResult;
use libtock::timer::DriverContext;
use libtock::timer::Duration;

#[libtock::main]
async fn main() -> TockResult<()> {
    let mut drivers = libtock::retrieve_drivers()?;

    let mut test = LibtockTest::initialize(drivers.console);

    let test_result = libtock_test(&mut test, &mut drivers.timer, &mut drivers.gpio).await;

    if test_result.is_ok() && test.is_success() {
        test.log_success("Test suite finished with state SUCCESS")
    } else {
        test.log_failure("Test suite finished with state FAILURE")
    }
}

async fn libtock_test(
    test: &mut LibtockTest,
    timer: &mut DriverContext,
    gpio: &mut GpioDriverFactory,
) -> TockResult<()> {
    test.console()?;
    test.static_mut()?;
    test.dynamic_dispatch()?;
    test.formatting()?;
    test.heap()?;
    test.callbacks(timer).await?;
    test.gpio(gpio)?;
    Ok(())
}

struct LibtockTest {
    console: Console,
    success: bool,
}

impl LibtockTest {
    fn initialize(console: ConsoleDriver) -> Self {
        Self {
            console: console.create_console(),
            success: true,
        }
    }

    fn console(&mut self) -> TockResult<()> {
        self.log_success("Console")
    }

    fn static_mut(&mut self) -> TockResult<()> {
        self.check_if_true(increment_static_mut() == 1, "static mut")
    }

    fn dynamic_dispatch(&mut self) -> TockResult<()> {
        let (x, y) = if foo() == "foo" {
            (&'0' as &dyn MyTrait, &0usize as &dyn MyTrait)
        } else {
            (&0usize as &dyn MyTrait, &'0' as &dyn MyTrait)
        };

        self.check_if_true(
            (x.dispatch(), y.dispatch()) == ("str", "usize"),
            "Dynamic dispatch",
        )
    }

    fn formatting(&mut self) -> TockResult<()> {
        let mut string = String::new();
        write!(string, "{}bar", foo())?;

        self.check_if_true(string == "foobar", "Formatting")
    }

    fn heap(&mut self) -> TockResult<()> {
        let mut string = String::new();
        string.push_str(foo());
        string.push_str("bar");

        self.check_if_true(string == "foobar", "Heap")
    }

    async fn callbacks(&mut self, timer_context: &mut DriverContext) -> TockResult<()> {
        let mut callback_hit = false;
        let mut with_callback = timer_context.with_callback(|_, _| callback_hit = true);
        let mut timer = with_callback.init()?;

        timer.set_alarm(Duration::from_ms(50))?;

        AlternatingFuture { yielded: false }.await;

        mem::drop(timer);

        self.check_if_true(callback_hit, "Callbacks")
    }

    fn gpio(&mut self, gpio: &mut GpioDriverFactory) -> TockResult<()> {
        let mut gpio_driver = gpio.init_driver().ok().unwrap();

        self.log_success("GPIO initialization")?;

        let mut gpios = gpio_driver.gpios();
        let mut pin_in = gpios.next().unwrap();
        let pin_in = pin_in.enable_input(ResistorMode::PullDown).ok().unwrap();
        let mut pin_out = gpios.next().unwrap();
        let pin_out = pin_out.enable_output().ok().unwrap();

        self.log_success("GPIO activation")?;

        pin_out.set_high().ok().unwrap();

        self.check_if_true(
            pin_in.read().ok() == Some(GpioState::High),
            "GPIO read/write",
        )
    }

    fn is_success(&self) -> bool {
        self.success
    }

    fn check_if_true(&mut self, condition: bool, message: &str) -> TockResult<()> {
        if condition {
            self.log_success(message)
        } else {
            self.log_failure(message)
        }
    }

    fn log_success(&mut self, message: &str) -> TockResult<()> {
        writeln!(&mut self.console, "[      OK ] {}", message)?;
        Ok(())
    }

    fn log_failure(&mut self, message: &str) -> TockResult<()> {
        writeln!(&mut self.console, "[ FAILURE ] {}", message)?;
        self.success = false;
        Ok(())
    }
}

#[inline(never)]
// Do not inline this to prevent compiler optimizations
fn foo() -> &'static str {
    "foo"
}

#[inline(never)]
fn increment_static_mut() -> usize {
    static mut STATIC: usize = 0;

    unsafe {
        STATIC += 1;
        STATIC
    }
}

trait MyTrait {
    fn dispatch(&self) -> &'static str;
}

impl MyTrait for usize {
    fn dispatch(&self) -> &'static str {
        "usize"
    }
}

impl MyTrait for char {
    fn dispatch(&self) -> &'static str {
        "str"
    }
}

struct AlternatingFuture {
    yielded: bool,
}

impl Future for AlternatingFuture {
    type Output = ();

    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
        self.yielded = !self.yielded;
        if self.yielded {
            Poll::Pending
        } else {
            Poll::Ready(())
        }
    }
}
