use std::fs::File;
use std::hash::{Hash, Hasher};
use std::io;
use std::os::windows::io::{
    AsRawHandle, IntoRawHandle, RawHandle,
};
use std::path::Path;

use winapi_util as winutil;

// For correctness, it is critical that both file handles remain open while
// their attributes are checked for equality. In particular, the file index
// numbers on a Windows stat object are not guaranteed to remain stable over
// time.
//
// See the docs and remarks on MSDN:
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788(v=vs.85).aspx
//
// It gets worse. It appears that the index numbers are not always
// guaranteed to be unique. Namely, ReFS uses 128 bit numbers for unique
// identifiers. This requires a distinct syscall to get `FILE_ID_INFO`
// documented here:
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh802691(v=vs.85).aspx
//
// It seems straight-forward enough to modify this code to use
// `FILE_ID_INFO` when available (minimum Windows Server 2012), but I don't
// have access to such Windows machines.
//
// Two notes.
//
// 1. Java's NIO uses the approach implemented here and appears to ignore
//    `FILE_ID_INFO` altogether. So Java's NIO and this code are
//    susceptible to bugs when running on a file system where
//    `nFileIndex{Low,High}` are not unique.
//
// 2. LLVM has a bug where they fetch the id of a file and continue to use
//    it even after the handle has been closed, so that uniqueness is no
//    longer guaranteed (when `nFileIndex{Low,High}` are unique).
//    bug report: http://lists.llvm.org/pipermail/llvm-bugs/2014-December/037218.html
//
// All said and done, checking whether two files are the same on Windows
// seems quite tricky. Moreover, even if the code is technically incorrect,
// it seems like the chances of actually observing incorrect behavior are
// extremely small. Nevertheless, we mitigate this by checking size too.
//
// In the case where this code is erroneous, two files will be reported
// as equivalent when they are in fact distinct. This will cause the loop
// detection code to report a false positive, which will prevent descending
// into the offending directory. As far as failure modes goes, this isn't
// that bad.

#[derive(Debug)]
pub struct Handle {
    kind: HandleKind,
    key: Option<Key>,
}

#[derive(Debug)]
enum HandleKind {
    /// Used when opening a file or acquiring ownership of a file.
    Owned(winutil::Handle),
    /// Used for stdio.
    Borrowed(winutil::HandleRef),
}

#[derive(Debug, Eq, PartialEq, Hash)]
struct Key {
    volume: u64,
    index: u64,
}

impl Eq for Handle {}

impl PartialEq for Handle {
    fn eq(&self, other: &Handle) -> bool {
        // Need this branch to satisfy `Eq` since `Handle`s with
        // `key.is_none()` wouldn't otherwise.
        if self as *const Handle == other as *const Handle {
            return true;
        } else if self.key.is_none() || other.key.is_none() {
            return false;
        }
        self.key == other.key
    }
}

impl AsRawHandle for ::Handle {
    fn as_raw_handle(&self) -> RawHandle {
        match self.0.kind {
            HandleKind::Owned(ref h) => h.as_raw_handle(),
            HandleKind::Borrowed(ref h) => h.as_raw_handle(),
        }
    }
}

impl IntoRawHandle for ::Handle {
    fn into_raw_handle(self) -> RawHandle {
        match self.0.kind {
            HandleKind::Owned(h) => h.into_raw_handle(),
            HandleKind::Borrowed(h) => h.as_raw_handle(),
        }
    }
}

impl Hash for Handle {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.key.hash(state);
    }
}

impl Handle {
    pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> {
        let h = winutil::Handle::from_path_any(p)?;
        let info = winutil::file::information(&h)?;
        Ok(Handle::from_info(HandleKind::Owned(h), info))
    }

    pub fn from_file(file: File) -> io::Result<Handle> {
        let h = winutil::Handle::from_file(file);
        let info = winutil::file::information(&h)?;
        Ok(Handle::from_info(HandleKind::Owned(h), info))
    }

    fn from_std_handle(h: winutil::HandleRef) -> io::Result<Handle> {
        match winutil::file::information(&h) {
            Ok(info) => Ok(Handle::from_info(HandleKind::Borrowed(h), info)),
            // In a Windows console, if there is no pipe attached to a STD
            // handle, then GetFileInformationByHandle will return an error.
            // We don't really care. The only thing we care about is that
            // this handle is never equivalent to any other handle, which is
            // accomplished by setting key to None.
            Err(_) => Ok(Handle { kind: HandleKind::Borrowed(h), key: None }),
        }
    }

    fn from_info(
        kind: HandleKind,
        info: winutil::file::Information,
    ) -> Handle {
        Handle {
            kind: kind,
            key: Some(Key {
                volume: info.volume_serial_number(),
                index: info.file_index(),
            }),
        }
    }

    pub fn stdin() -> io::Result<Handle> {
        Handle::from_std_handle(winutil::HandleRef::stdin())
    }

    pub fn stdout() -> io::Result<Handle> {
        Handle::from_std_handle(winutil::HandleRef::stdout())
    }

    pub fn stderr() -> io::Result<Handle> {
        Handle::from_std_handle(winutil::HandleRef::stderr())
    }

    pub fn as_file(&self) -> &File {
        match self.kind {
            HandleKind::Owned(ref h) => h.as_file(),
            HandleKind::Borrowed(ref h) => h.as_file(),
        }
    }

    pub fn as_file_mut(&mut self) -> &mut File {
        match self.kind {
            HandleKind::Owned(ref mut h) => h.as_file_mut(),
            HandleKind::Borrowed(ref mut h) => h.as_file_mut(),
        }
    }
}
