use crate::{BOOL, FALSE, TRUE};
use std::cmp;
use std::io;
use std::ptr;

use windows_sys::Win32::Foundation::{CloseHandle, ERROR_IO_INCOMPLETE, ERROR_IO_PENDING, HANDLE};
use windows_sys::Win32::Storage::FileSystem::{ReadFile, WriteFile};
use windows_sys::Win32::System::IO::{GetOverlappedResult, OVERLAPPED};

#[derive(Debug)]
pub struct Handle(HANDLE);

unsafe impl Send for Handle {}
unsafe impl Sync for Handle {}

impl Handle {
    pub fn new(handle: HANDLE) -> Handle {
        Handle(handle)
    }

    pub fn raw(&self) -> HANDLE {
        self.0
    }

    pub fn into_raw(self) -> HANDLE {
        use std::mem;

        let ret = self.0;
        mem::forget(self);
        ret
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        let mut bytes = 0;
        let len = cmp::min(buf.len(), <u32>::max_value() as usize) as u32;
        crate::cvt(unsafe {
            WriteFile(
                self.0,
                buf.as_ptr() as *const _,
                len,
                &mut bytes,
                0 as *mut _,
            )
        })?;
        Ok(bytes as usize)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes = 0;
        let len = cmp::min(buf.len(), <u32>::max_value() as usize) as u32;
        crate::cvt(unsafe {
            ReadFile(
                self.0,
                buf.as_mut_ptr() as *mut _,
                len,
                &mut bytes,
                0 as *mut _,
            )
        })?;
        Ok(bytes as usize)
    }

    pub unsafe fn read_overlapped(
        &self,
        buf: &mut [u8],
        overlapped: *mut OVERLAPPED,
    ) -> io::Result<Option<usize>> {
        self.read_overlapped_helper(buf, overlapped, FALSE)
    }

    pub unsafe fn read_overlapped_wait(
        &self,
        buf: &mut [u8],
        overlapped: *mut OVERLAPPED,
    ) -> io::Result<usize> {
        match self.read_overlapped_helper(buf, overlapped, TRUE) {
            Ok(Some(bytes)) => Ok(bytes),
            Ok(None) => panic!("logic error"),
            Err(e) => Err(e),
        }
    }

    pub unsafe fn read_overlapped_helper(
        &self,
        buf: &mut [u8],
        overlapped: *mut OVERLAPPED,
        wait: BOOL,
    ) -> io::Result<Option<usize>> {
        let len = cmp::min(buf.len(), <u32>::max_value() as usize) as u32;
        let res = crate::cvt({
            ReadFile(
                self.0,
                buf.as_mut_ptr() as *mut _,
                len,
                ptr::null_mut(),
                overlapped,
            )
        });
        match res {
            Ok(_) => (),
            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32) => (),
            Err(e) => return Err(e),
        }

        let mut bytes = 0;
        let res = crate::cvt(GetOverlappedResult(self.0, overlapped, &mut bytes, wait));
        match res {
            Ok(_) => Ok(Some(bytes as usize)),
            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_INCOMPLETE as i32) && wait == FALSE => {
                Ok(None)
            }
            Err(e) => Err(e),
        }
    }

    pub unsafe fn write_overlapped(
        &self,
        buf: &[u8],
        overlapped: *mut OVERLAPPED,
    ) -> io::Result<Option<usize>> {
        self.write_overlapped_helper(buf, overlapped, FALSE)
    }

    pub unsafe fn write_overlapped_wait(
        &self,
        buf: &[u8],
        overlapped: *mut OVERLAPPED,
    ) -> io::Result<usize> {
        match self.write_overlapped_helper(buf, overlapped, TRUE) {
            Ok(Some(bytes)) => Ok(bytes),
            Ok(None) => panic!("logic error"),
            Err(e) => Err(e),
        }
    }

    unsafe fn write_overlapped_helper(
        &self,
        buf: &[u8],
        overlapped: *mut OVERLAPPED,
        wait: BOOL,
    ) -> io::Result<Option<usize>> {
        let len = cmp::min(buf.len(), <u32>::max_value() as usize) as u32;
        let res = crate::cvt({
            WriteFile(
                self.0,
                buf.as_ptr() as *const _,
                len,
                ptr::null_mut(),
                overlapped,
            )
        });
        match res {
            Ok(_) => (),
            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32) => (),
            Err(e) => return Err(e),
        }

        let mut bytes = 0;
        let res = crate::cvt(GetOverlappedResult(self.0, overlapped, &mut bytes, wait));
        match res {
            Ok(_) => Ok(Some(bytes as usize)),
            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_INCOMPLETE as i32) && wait == FALSE => {
                Ok(None)
            }
            Err(e) => Err(e),
        }
    }
}

impl Drop for Handle {
    fn drop(&mut self) {
        unsafe { CloseHandle(self.0) };
    }
}
