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

#![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")
    }
}

#[cfg_attr(
    feature = "__internal_disable_gpio_in_integration_test",
    allow(unused_variables)
)]
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.drivers_only_instantiable_once()?;
    #[cfg(not(feature = "__internal_disable_timer_in_integration_test"))]
    test.callbacks(timer).await?;
    #[cfg(not(feature = "__internal_disable_gpio_in_integration_test"))]
    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")
    }

    fn drivers_only_instantiable_once(&mut self) -> TockResult<()> {
        self.check_if_true(
            libtock::retrieve_drivers().is_err(),
            "Drivers only instantiable once",
        )
    }

    #[cfg_attr(
        feature = "__internal_disable_timer_in_integration_test",
        allow(dead_code)
    )]
    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(1000))?;

        AlternatingFuture { yielded: false }.await;

        mem::drop(timer);

        self.check_if_true(callback_hit, "Callbacks")
    }

    #[cfg_attr(
        feature = "__internal_disable_gpio_in_integration_test",
        allow(dead_code)
    )]
    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(())
        }
    }
}
