//! `wasmeld:clock/monotonic-clock@0.1.0` host implementation.

use std::time::Instant;

use wasmtime::component::Linker;

use crate::{RuntimeError, runtime::HostState};

wasmtime::component::bindgen!({
    path: "../../wit/clock",
    world: "clock-host",
});

pub(crate) const INTERFACE: &str = "wasmeld:clock/monotonic-clock@0.1.0";
pub(crate) const PACKAGE: &str = "wasmeld:clock";
pub(crate) const NAME: &str = "monotonic-clock";
pub(crate) const VERSION: &str = "0.1.0";

pub(crate) struct ClockState {
    origin: Instant,
}

impl ClockState {
    pub(crate) fn new() -> Self {
        Self {
            origin: Instant::now(),
        }
    }

    pub(crate) fn now(&self) -> u64 {
        u64::try_from(self.origin.elapsed().as_nanos()).unwrap_or(u64::MAX)
    }
}

impl wasmeld::clock::monotonic_clock::Host for HostState {
    fn now(&mut self) -> u64 {
        self.capabilities.monotonic_clock_now()
    }
}

pub(crate) fn add_to_linker(linker: &mut Linker<HostState>) -> Result<(), RuntimeError> {
    wasmeld::clock::monotonic_clock::add_to_linker::<HostState, HostState>(linker, |state| state)
        .map_err(|error| RuntimeError::ActorInitialization(error.to_string()))
}
