// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Bindings to libuv, along with the default implementation of `std::rt::rtio`.

UV types consist of the event loop (Loop), Watchers, Requests and
Callbacks.

Watchers and Requests encapsulate pointers to uv *handles*, which have
subtyping relationships with each other.  This subtyping is reflected
in the bindings with explicit or implicit coercions. For example, an
upcast from TcpWatcher to StreamWatcher is done with
`tcp_watcher.as_stream()`. In other cases a callback on a specific
type of watcher will be passed a watcher of a supertype.

Currently all use of Request types (connect/write requests) are
encapsulated in the bindings and don't need to be dealt with by the
caller.

# Safety note

Due to the complex lifecycle of uv handles, as well as compiler bugs,
this module is not memory safe and requires explicit memory management,
via `close` and `delete` methods.

*/

#![crate_id = "rustuv#0.11.0"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/0.11.0/",
       html_playground_url = "http://play.rust-lang.org/")]

#![feature(macro_rules, unsafe_destructor)]
#![deny(unused_result, unused_must_use)]
#![allow(visible_private_types)]

#[cfg(test)] extern crate green;
#[cfg(test)] extern crate debug;
#[cfg(test)] extern crate realrustuv = "rustuv";
extern crate libc;
extern crate alloc;

use libc::{c_int, c_void};
use std::fmt;
use std::mem;
use std::ptr::null;
use std::ptr;
use std::rt::local::Local;
use std::rt::rtio;
use std::rt::rtio::{IoResult, IoError};
use std::rt::task::{BlockedTask, Task};
use std::str::raw::from_c_str;
use std::task;

pub use self::async::AsyncWatcher;
pub use self::file::{FsRequest, FileWatcher};
pub use self::idle::IdleWatcher;
pub use self::net::{TcpWatcher, TcpListener, TcpAcceptor, UdpWatcher};
pub use self::pipe::{PipeWatcher, PipeListener, PipeAcceptor};
pub use self::process::Process;
pub use self::signal::SignalWatcher;
pub use self::timer::TimerWatcher;
pub use self::tty::TtyWatcher;

// Run tests with libgreen instead of libnative.
//
// FIXME: This egregiously hacks around starting the test runner in a different
//        threading mode than the default by reaching into the auto-generated
//        '__test' module.
#[cfg(test)] #[start]
fn start(argc: int, argv: **u8) -> int {
    green::start(argc, argv, event_loop, __test::main)
}

mod macros;

mod access;
mod timeout;
mod homing;
mod queue;
mod rc;

pub mod uvio;
pub mod uvll;

pub mod file;
pub mod net;
pub mod idle;
pub mod timer;
pub mod async;
pub mod addrinfo;
pub mod process;
pub mod pipe;
pub mod tty;
pub mod signal;
pub mod stream;

/// Creates a new event loop which is powered by libuv
///
/// This function is used in tandem with libgreen's `PoolConfig` type as a value
/// for the `event_loop_factory` field. Using this function as the event loop
/// factory will power programs with libuv and enable green threading.
///
/// # Example
///
/// ```
/// extern crate rustuv;
/// extern crate green;
///
/// #[start]
/// fn start(argc: int, argv: **u8) -> int {
///     green::start(argc, argv, rustuv::event_loop, main)
/// }
///
/// fn main() {
///     // this code is running inside of a green task powered by libuv
/// }
/// ```
pub fn event_loop() -> Box<rtio::EventLoop + Send> {
    box uvio::UvEventLoop::new() as Box<rtio::EventLoop + Send>
}

/// A type that wraps a uv handle
pub trait UvHandle<T> {
    fn uv_handle(&self) -> *T;

    fn uv_loop(&self) -> Loop {
        Loop::wrap(unsafe { uvll::get_loop_for_uv_handle(self.uv_handle()) })
    }

    // FIXME(#8888) dummy self
    fn alloc(_: Option<Self>, ty: uvll::uv_handle_type) -> *T {
        unsafe {
            let handle = uvll::malloc_handle(ty);
            assert!(!handle.is_null());
            handle as *T
        }
    }

    unsafe fn from_uv_handle<'a>(h: &'a *T) -> &'a mut Self {
        mem::transmute(uvll::get_data_for_uv_handle(*h))
    }

    fn install(~self) -> Box<Self> {
        unsafe {
            let myptr = mem::transmute::<&Box<Self>, &*u8>(&self);
            uvll::set_data_for_uv_handle(self.uv_handle(), *myptr);
        }
        self
    }

    fn close_async_(&mut self) {
        // we used malloc to allocate all handles, so we must always have at
        // least a callback to free all the handles we allocated.
        extern fn close_cb(handle: *uvll::uv_handle_t) {
            unsafe { uvll::free_handle(handle) }
        }

        unsafe {
            uvll::set_data_for_uv_handle(self.uv_handle(), null::<()>());
            uvll::uv_close(self.uv_handle() as *uvll::uv_handle_t, close_cb)
        }
    }

    fn close(&mut self) {
        let mut slot = None;

        unsafe {
            uvll::uv_close(self.uv_handle() as *uvll::uv_handle_t, close_cb);
            uvll::set_data_for_uv_handle(self.uv_handle(), ptr::null::<()>());

            wait_until_woken_after(&mut slot, &self.uv_loop(), || {
                uvll::set_data_for_uv_handle(self.uv_handle(), &slot);
            })
        }

        extern fn close_cb(handle: *uvll::uv_handle_t) {
            unsafe {
                let data = uvll::get_data_for_uv_handle(handle);
                uvll::free_handle(handle);
                if data == ptr::null() { return }
                let slot: &mut Option<BlockedTask> = mem::transmute(data);
                wakeup(slot);
            }
        }
    }
}

pub struct ForbidSwitch {
    msg: &'static str,
    io: uint,
}

impl ForbidSwitch {
    fn new(s: &'static str) -> ForbidSwitch {
        ForbidSwitch {
            msg: s,
            io: homing::local_id(),
        }
    }
}

impl Drop for ForbidSwitch {
    fn drop(&mut self) {
        assert!(self.io == homing::local_id(),
                "didn't want a scheduler switch: {}",
                self.msg);
    }
}

pub struct ForbidUnwind {
    msg: &'static str,
    failing_before: bool,
}

impl ForbidUnwind {
    fn new(s: &'static str) -> ForbidUnwind {
        ForbidUnwind {
            msg: s, failing_before: task::failing(),
        }
    }
}

impl Drop for ForbidUnwind {
    fn drop(&mut self) {
        assert!(self.failing_before == task::failing(),
                "didnt want an unwind during: {}", self.msg);
    }
}

fn wait_until_woken_after(slot: *mut Option<BlockedTask>,
                          loop_: &Loop,
                          f: ||) {
    let _f = ForbidUnwind::new("wait_until_woken_after");
    unsafe {
        assert!((*slot).is_none());
        let task: Box<Task> = Local::take();
        loop_.modify_blockers(1);
        task.deschedule(1, |task| {
            *slot = Some(task);
            f();
            Ok(())
        });
        loop_.modify_blockers(-1);
    }
}

fn wakeup(slot: &mut Option<BlockedTask>) {
    assert!(slot.is_some());
    let _ = slot.take_unwrap().wake().map(|t| t.reawaken());
}

pub struct Request {
    pub handle: *uvll::uv_req_t,
    defused: bool,
}

impl Request {
    pub fn new(ty: uvll::uv_req_type) -> Request {
        unsafe {
            let handle = uvll::malloc_req(ty);
            uvll::set_data_for_req(handle, null::<()>());
            Request::wrap(handle)
        }
    }

    pub fn wrap(handle: *uvll::uv_req_t) -> Request {
        Request { handle: handle, defused: false }
    }

    pub fn set_data<T>(&self, t: *T) {
        unsafe { uvll::set_data_for_req(self.handle, t) }
    }

    pub unsafe fn get_data<T>(&self) -> &'static mut T {
        let data = uvll::get_data_for_req(self.handle);
        assert!(data != null());
        mem::transmute(data)
    }

    // This function should be used when the request handle has been given to an
    // underlying uv function, and the uv function has succeeded. This means
    // that uv will at some point invoke the callback, and in the meantime we
    // can't deallocate the handle because libuv could be using it.
    //
    // This is still a problem in blocking situations due to linked failure. In
    // the connection callback the handle should be re-wrapped with the `wrap`
    // function to ensure its destruction.
    pub fn defuse(&mut self) {
        self.defused = true;
    }
}

impl Drop for Request {
    fn drop(&mut self) {
        if !self.defused {
            unsafe { uvll::free_req(self.handle) }
        }
    }
}

/// FIXME: Loop(*handle) is buggy with destructors. Normal structs
/// with dtors may not be destructured, but tuple structs can,
/// but the results are not correct.
pub struct Loop {
    handle: *uvll::uv_loop_t
}

impl Loop {
    pub fn new() -> Loop {
        let handle = unsafe { uvll::loop_new() };
        assert!(handle.is_not_null());
        unsafe { uvll::set_data_for_uv_loop(handle, 0 as *c_void) }
        Loop::wrap(handle)
    }

    pub fn wrap(handle: *uvll::uv_loop_t) -> Loop { Loop { handle: handle } }

    pub fn run(&mut self) {
        assert_eq!(unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) }, 0);
    }

    pub fn close(&mut self) {
        unsafe { uvll::uv_loop_delete(self.handle) };
    }

    // The 'data' field of the uv_loop_t is used to count the number of tasks
    // that are currently blocked waiting for I/O to complete.
    fn modify_blockers(&self, amt: uint) {
        unsafe {
            let cur = uvll::get_data_for_uv_loop(self.handle) as uint;
            uvll::set_data_for_uv_loop(self.handle, (cur + amt) as *c_void)
        }
    }

    fn get_blockers(&self) -> uint {
        unsafe { uvll::get_data_for_uv_loop(self.handle) as uint }
    }
}

// FIXME: Need to define the error constants like EOF so they can be
// compared to the UvError type

pub struct UvError(c_int);

impl UvError {
    pub fn name(&self) -> String {
        unsafe {
            let inner = match self { &UvError(a) => a };
            let name_str = uvll::uv_err_name(inner);
            assert!(name_str.is_not_null());
            from_c_str(name_str).to_string()
        }
    }

    pub fn desc(&self) -> String {
        unsafe {
            let inner = match self { &UvError(a) => a };
            let desc_str = uvll::uv_strerror(inner);
            assert!(desc_str.is_not_null());
            from_c_str(desc_str).to_string()
        }
    }

    pub fn is_eof(&self) -> bool {
        let UvError(handle) = *self;
        handle == uvll::EOF
    }
}

impl fmt::Show for UvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}: {}", self.name(), self.desc())
    }
}

#[test]
fn error_smoke_test() {
    let err: UvError = UvError(uvll::EOF);
    assert_eq!(err.to_str(), "EOF: end of file".to_string());
}

#[cfg(unix)]
pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
    let UvError(errcode) = uverr;
    IoError {
        code: if errcode == uvll::EOF {libc::EOF as uint} else {-errcode as uint},
        extra: 0,
        detail: Some(uverr.desc()),
    }
}

#[cfg(windows)]
pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
    let UvError(errcode) = uverr;
    IoError {
        code: match errcode {
            uvll::EOF => libc::EOF,
            uvll::EACCES => libc::ERROR_ACCESS_DENIED,
            uvll::ECONNREFUSED => libc::WSAECONNREFUSED,
            uvll::ECONNRESET => libc::WSAECONNRESET,
            uvll::ENOTCONN => libc::WSAENOTCONN,
            uvll::ENOENT => libc::ERROR_FILE_NOT_FOUND,
            uvll::EPIPE => libc::ERROR_NO_DATA,
            uvll::ECONNABORTED => libc::WSAECONNABORTED,
            uvll::EADDRNOTAVAIL => libc::WSAEADDRNOTAVAIL,
            uvll::ECANCELED => libc::ERROR_OPERATION_ABORTED,
            uvll::EADDRINUSE => libc::WSAEADDRINUSE,
            err => {
                uvdebug!("uverr.code {}", err as int);
                // FIXME: Need to map remaining uv error types
                -1
            }
        } as uint,
        extra: 0,
        detail: Some(uverr.desc()),
    }
}

/// Given a uv error code, convert a callback status to a UvError
pub fn status_to_maybe_uv_error(status: c_int) -> Option<UvError> {
    if status >= 0 {
        None
    } else {
        Some(UvError(status))
    }
}

pub fn status_to_io_result(status: c_int) -> IoResult<()> {
    if status >= 0 {Ok(())} else {Err(uv_error_to_io_error(UvError(status)))}
}

/// The uv buffer type
pub type Buf = uvll::uv_buf_t;

pub fn empty_buf() -> Buf {
    uvll::uv_buf_t {
        base: null(),
        len: 0,
    }
}

/// Borrow a slice to a Buf
pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
    let data = v.as_ptr();
    uvll::uv_buf_t { base: data, len: v.len() as uvll::uv_buf_len_t }
}

// This function is full of lies!
#[cfg(test)]
fn local_loop() -> &'static mut uvio::UvIoFactory {
    unsafe {
        mem::transmute({
            let mut task = Local::borrow(None::<Task>);
            let mut io = task.local_io().unwrap();
            let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) =
                mem::transmute(io.get());
            uvio
        })
    }
}

#[cfg(test)]
fn next_test_ip4() -> std::rt::rtio::SocketAddr {
    use std::io;
    use std::rt::rtio;

    let io::net::ip::SocketAddr { ip, port } = io::test::next_test_ip4();
    let ip = match ip {
        io::net::ip::Ipv4Addr(a, b, c, d) => rtio::Ipv4Addr(a, b, c, d),
        _ => unreachable!(),
    };
    rtio::SocketAddr { ip: ip, port: port }
}

#[cfg(test)]
fn next_test_ip6() -> std::rt::rtio::SocketAddr {
    use std::io;
    use std::rt::rtio;

    let io::net::ip::SocketAddr { ip, port } = io::test::next_test_ip6();
    let ip = match ip {
        io::net::ip::Ipv6Addr(a, b, c, d, e, f, g, h) =>
            rtio::Ipv6Addr(a, b, c, d, e, f, g, h),
        _ => unreachable!(),
    };
    rtio::SocketAddr { ip: ip, port: port }
}

#[cfg(test)]
mod test {
    use std::mem::transmute;
    use std::rt::thread::Thread;

    use super::{slice_to_uv_buf, Loop};

    #[test]
    fn test_slice_to_uv_buf() {
        let slice = [0, .. 20];
        let buf = slice_to_uv_buf(slice);

        assert_eq!(buf.len, 20);

        unsafe {
            let base = transmute::<*u8, *mut u8>(buf.base);
            (*base) = 1;
            (*base.offset(1)) = 2;
        }

        assert!(slice[0] == 1);
        assert!(slice[1] == 2);
    }


    #[test]
    fn loop_smoke_test() {
        Thread::start(proc() {
            let mut loop_ = Loop::new();
            loop_.run();
            loop_.close();
        }).join();
    }
}
