use std::fs;
use std::io::{self, Read, Seek, Write};
use std::path::{Path, PathBuf};

use crate::errors::{Error, ErrorKind};
use crate::OpenOptions;

/// Wrapper around [`std::fs::File`][std::fs::File] which adds more helpful
/// information to all errors.
///
/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
#[derive(Debug)]
pub struct File {
    file: fs::File,
    path: PathBuf,
}

// Opens a std File and returns it or an error generator which only needs the path to produce the error.
// Exists for the `crate::read*` functions so they don't unconditionally build a PathBuf.
pub(crate) fn open(path: &Path) -> Result<std::fs::File, impl FnOnce(PathBuf) -> io::Error> {
    fs::File::open(path).map_err(|err| |path| Error::build(err, ErrorKind::OpenFile, path))
}

// like `open()` but for `crate::write`
pub(crate) fn create(path: &Path) -> Result<std::fs::File, impl FnOnce(PathBuf) -> io::Error> {
    fs::File::create(path).map_err(|err| |path| Error::build(err, ErrorKind::CreateFile, path))
}

/// Wrappers for methods from [`std::fs::File`][std::fs::File].
///
/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
impl File {
    /// Attempts to open a file in read-only mode.
    ///
    /// Wrapper for [`File::open`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.open).
    pub fn open<P>(path: P) -> Result<Self, io::Error>
    where
        P: Into<PathBuf>,
    {
        let path = path.into();
        match open(&path) {
            Ok(file) => Ok(File::from_parts(file, path)),
            Err(err_gen) => Err(err_gen(path)),
        }
    }

    /// Opens a file in write-only mode.
    ///
    /// Wrapper for [`File::create`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.create).
    pub fn create<P>(path: P) -> Result<Self, io::Error>
    where
        P: Into<PathBuf>,
    {
        let path = path.into();
        match create(&path) {
            Ok(file) => Ok(File::from_parts(file, path)),
            Err(err_gen) => Err(err_gen(path)),
        }
    }

    /// Opens a file in read-write mode.
    ///
    /// Wrapper for [`File::create_new`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.create_new).
    pub fn create_new<P>(path: P) -> Result<Self, io::Error>
    where
        P: Into<PathBuf>,
    {
        let path = path.into();
        // TODO: Use fs::File::create_new once MSRV is at least 1.77
        match fs::OpenOptions::new()
            .read(true)
            .write(true)
            .create_new(true)
            .open(&path)
        {
            Ok(file) => Ok(File::from_parts(file, path)),
            Err(err) => Err(Error::build(err, ErrorKind::CreateFile, path)),
        }
    }

    /// Returns a new `OpenOptions` object.
    ///
    /// Wrapper for [`File::options`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.options).
    pub fn options() -> OpenOptions {
        OpenOptions::new()
    }

    /// Attempts to sync all OS-internal metadata to disk.
    ///
    /// Wrapper for [`File::sync_all`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.sync_all).
    pub fn sync_all(&self) -> Result<(), io::Error> {
        self.file
            .sync_all()
            .map_err(|source| self.error(source, ErrorKind::SyncFile))
    }

    /// This function is similar to [`sync_all`], except that it might not synchronize file metadata to the filesystem.
    ///
    /// Wrapper for [`File::sync_data`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.sync_data).
    pub fn sync_data(&self) -> Result<(), io::Error> {
        self.file
            .sync_data()
            .map_err(|source| self.error(source, ErrorKind::SyncFile))
    }

    /// Truncates or extends the underlying file, updating the size of this file to become `size`.
    ///
    /// Wrapper for [`File::set_len`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.set_len).
    pub fn set_len(&self, size: u64) -> Result<(), io::Error> {
        self.file
            .set_len(size)
            .map_err(|source| self.error(source, ErrorKind::SetLen))
    }

    /// Queries metadata about the underlying file.
    ///
    /// Wrapper for [`File::metadata`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.metadata).
    pub fn metadata(&self) -> Result<fs::Metadata, io::Error> {
        self.file
            .metadata()
            .map_err(|source| self.error(source, ErrorKind::Metadata))
    }

    /// Creates a new `File` instance that shares the same underlying file handle as the
    /// existing `File` instance. Reads, writes, and seeks will affect both `File`
    /// instances simultaneously.
    ///
    /// Wrapper for [`File::try_clone`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.try_clone).
    pub fn try_clone(&self) -> Result<Self, io::Error> {
        self.file
            .try_clone()
            .map(|file| File {
                file,
                path: self.path.clone(),
            })
            .map_err(|source| self.error(source, ErrorKind::Clone))
    }

    /// Changes the permissions on the underlying file.
    ///
    /// Wrapper for [`File::set_permissions`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.set_permissions).
    pub fn set_permissions(&self, perm: fs::Permissions) -> Result<(), io::Error> {
        self.file
            .set_permissions(perm)
            .map_err(|source| self.error(source, ErrorKind::SetPermissions))
    }
}

/// Methods added by fs-err that are not available on
/// [`std::fs::File`][std::fs::File].
///
/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
impl File {
    /// Creates a [`File`](struct.File.html) from a raw file and its path.
    pub fn from_parts<P>(file: fs::File, path: P) -> Self
    where
        P: Into<PathBuf>,
    {
        File {
            file,
            path: path.into(),
        }
    }

    /// Extract the raw file and its path from this [`File`](struct.File.html)
    pub fn into_parts(self) -> (fs::File, PathBuf) {
        (self.file, self.path)
    }

    /// Returns a reference to the underlying [`std::fs::File`][std::fs::File].
    ///
    /// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
    pub fn file(&self) -> &fs::File {
        &self.file
    }

    /// Returns a mutable reference to the underlying [`std::fs::File`][std::fs::File].
    ///
    /// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
    pub fn file_mut(&mut self) -> &mut fs::File {
        &mut self.file
    }

    /// Returns a reference to the path that this file was created with.
    pub fn path(&self) -> &Path {
        &self.path
    }

    /// Wrap the error in information specific to this `File` object.
    fn error(&self, source: io::Error, kind: ErrorKind) -> io::Error {
        Error::build(source, kind, &self.path)
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        self.file
            .read(buf)
            .map_err(|source| self.error(source, ErrorKind::Read))
    }

    fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
        self.file
            .read_vectored(bufs)
            .map_err(|source| self.error(source, ErrorKind::Read))
    }
}

impl Read for &File {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        (&self.file)
            .read(buf)
            .map_err(|source| self.error(source, ErrorKind::Read))
    }

    fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
        (&self.file)
            .read_vectored(bufs)
            .map_err(|source| self.error(source, ErrorKind::Read))
    }
}

impl From<File> for fs::File {
    fn from(file: File) -> Self {
        file.into_parts().0
    }
}

impl Seek for File {
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
        self.file
            .seek(pos)
            .map_err(|source| self.error(source, ErrorKind::Seek))
    }
}

impl Seek for &File {
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
        (&self.file)
            .seek(pos)
            .map_err(|source| self.error(source, ErrorKind::Seek))
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.file
            .write(buf)
            .map_err(|source| self.error(source, ErrorKind::Write))
    }

    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
        self.file
            .write_vectored(bufs)
            .map_err(|source| self.error(source, ErrorKind::Write))
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.file
            .flush()
            .map_err(|source| self.error(source, ErrorKind::Flush))
    }
}

impl Write for &File {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        (&self.file)
            .write(buf)
            .map_err(|source| self.error(source, ErrorKind::Write))
    }

    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
        (&self.file)
            .write_vectored(bufs)
            .map_err(|source| self.error(source, ErrorKind::Write))
    }

    fn flush(&mut self) -> std::io::Result<()> {
        (&self.file)
            .flush()
            .map_err(|source| self.error(source, ErrorKind::Flush))
    }
}

#[cfg(unix)]
mod unix {
    use crate::os::unix::fs::FileExt;
    use crate::ErrorKind;
    use std::io;
    use std::os::unix::fs::FileExt as _;
    use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};

    impl AsRawFd for crate::File {
        fn as_raw_fd(&self) -> RawFd {
            self.file().as_raw_fd()
        }
    }

    impl IntoRawFd for crate::File {
        fn into_raw_fd(self) -> RawFd {
            self.file.into_raw_fd()
        }
    }

    impl FileExt for crate::File {
        fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
            self.file()
                .read_at(buf, offset)
                .map_err(|err| self.error(err, ErrorKind::ReadAt))
        }
        fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
            self.file()
                .write_at(buf, offset)
                .map_err(|err| self.error(err, ErrorKind::WriteAt))
        }
    }

    #[cfg(rustc_1_63)]
    mod io_safety {
        use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};

        impl AsFd for crate::File {
            fn as_fd(&self) -> BorrowedFd<'_> {
                self.file().as_fd()
            }
        }

        impl From<crate::File> for OwnedFd {
            fn from(file: crate::File) -> Self {
                file.into_parts().0.into()
            }
        }
    }
}

#[cfg(windows)]
mod windows {
    use crate::os::windows::fs::FileExt;
    use crate::ErrorKind;
    use std::io;
    use std::os::windows::{
        fs::FileExt as _,
        io::{AsRawHandle, IntoRawHandle, RawHandle},
    };

    impl FileExt for crate::File {
        fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
            self.file()
                .seek_read(buf, offset)
                .map_err(|err| self.error(err, ErrorKind::SeekRead))
        }

        fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
            self.file()
                .seek_write(buf, offset)
                .map_err(|err| self.error(err, ErrorKind::SeekWrite))
        }
    }

    impl AsRawHandle for crate::File {
        fn as_raw_handle(&self) -> RawHandle {
            self.file().as_raw_handle()
        }
    }

    // can't be implemented, because the trait doesn't give us a Path
    // impl std::os::windows::io::FromRawHandle for crate::File {
    // }

    impl IntoRawHandle for crate::File {
        fn into_raw_handle(self) -> RawHandle {
            self.file.into_raw_handle()
        }
    }

    #[cfg(rustc_1_63)]
    mod io_safety {
        use std::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle};

        impl AsHandle for crate::File {
            fn as_handle(&self) -> BorrowedHandle<'_> {
                self.file().as_handle()
            }
        }

        impl From<crate::File> for OwnedHandle {
            fn from(file: crate::File) -> Self {
                file.into_parts().0.into()
            }
        }
    }
}
