use std::{
    io,
    os::{
        fd::{AsRawFd, RawFd},
        yggdrasil::io::poll::PollChannel,
    },
    time::Duration,
};

use crate::{io::PollEvent, sys::Poll};

pub struct PollImpl(PollChannel);

impl Poll for PollImpl {
    fn new() -> io::Result<Self> {
        PollChannel::new().map(Self)
    }

    fn add<F: AsRawFd>(&mut self, interest: &F) -> io::Result<()> {
        self.0.add(interest.as_raw_fd())
    }

    fn remove<F: AsRawFd>(&mut self, interest: &F) -> io::Result<()> {
        self.0.remove(interest.as_raw_fd())
    }

    fn wait(&mut self, timeout: Option<Duration>) -> io::Result<PollEvent> {
        let ev = match self.0.wait(timeout, true)? {
            Some((fd, Ok(_))) => PollEvent::Ready(fd),
            Some((fd, Err(e))) => PollEvent::Error(fd, e),
            None => PollEvent::None,
        };
        Ok(ev)
    }
}

impl AsRawFd for PollImpl {
    fn as_raw_fd(&self) -> RawFd {
        self.0.as_raw_fd()
    }
}
