use {io, poll, Evented, Ready, Poll, PollOpt, Token};
use sys::fuchsia::status_to_io_err;
use magenta;
use std::sync::{Arc, Mutex, Weak};

pub struct Awakener {
    /// Token and weak reference to the port on which Awakener was registered.
    ///
    /// When `Awakener::wakeup` is called, these are used to send a wakeup message to the port.
    inner: Mutex<Option<(Token, Weak<magenta::Port>)>>,
}

impl Awakener {
    /// Create a new `Awakener`.
    pub fn new() -> io::Result<Awakener> {
        Ok(Awakener {
            inner: Mutex::new(None)
        })
    }

    /// Send a wakeup signal to the `Selector` on which the `Awakener` was registered.
    pub fn wakeup(&self) -> io::Result<()> {
        let inner_locked = self.inner.lock().unwrap();
        let &(token, ref weak_port) =
            inner_locked.as_ref().expect("Called wakeup on unregistered awakener.");

        let port = weak_port.upgrade().expect("Tried to wakeup a closed port.");

        let status = 0; // arbitrary
        let packet = magenta::Packet::from_user_packet(
            token.0 as u64, status, magenta::UserPacket::from_u8_array([0; 32]));

        port.queue(&packet).map_err(status_to_io_err)
    }

    pub fn cleanup(&self) {}
}

impl Evented for Awakener {
    fn register(&self,
                poll: &Poll,
                token: Token,
                _events: Ready,
                _opts: PollOpt) -> io::Result<()>
    {
        let mut inner_locked = self.inner.lock().unwrap();
        if inner_locked.is_some() {
            panic!("Called register on already-registered Awakener.");
        }
        *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port())));

        Ok(())
    }

    fn reregister(&self,
                  poll: &Poll,
                  token: Token,
                  _events: Ready,
                  _opts: PollOpt) -> io::Result<()>
    {
        let mut inner_locked = self.inner.lock().unwrap();
        *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port())));

        Ok(())
    }

    fn deregister(&self, _poll: &Poll) -> io::Result<()>
    {
        let mut inner_locked = self.inner.lock().unwrap();
        *inner_locked = None;

        Ok(())
    }
}