#![allow(dead_code)]

use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::fmt;
use crate::fs::TryLockError;
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::mem::MaybeUninit;
use crate::os::raw::{c_int, c_short};
use crate::os::solid::ffi::OsStrExt;
use crate::path::{Path, PathBuf};
use crate::sync::Arc;
pub use crate::sys::fs::common::{Dir, exists};
use crate::sys::helpers::ignore_notfound;
use crate::sys::pal::{abi, error};
use crate::sys::time::SystemTime;
use crate::sys::{unsupported, unsupported_err};

type CIntNotMinusOne = core::num::niche_types::NotAllOnes<c_int>;

/// A file descriptor.
#[derive(Clone, Copy)]
struct FileDesc {
    fd: CIntNotMinusOne,
}

impl FileDesc {
    #[inline]
    #[track_caller]
    fn new(fd: c_int) -> FileDesc {
        FileDesc { fd: CIntNotMinusOne::new(fd).expect("fd != -1") }
    }

    #[inline]
    fn raw(&self) -> c_int {
        self.fd.as_inner()
    }
}

pub struct File {
    fd: FileDesc,
}

#[derive(Clone)]
pub struct FileAttr {
    stat: abi::stat,
}

// all DirEntry's will have a reference to this struct
struct InnerReadDir {
    dirp: abi::S_DIR,
    root: PathBuf,
}

pub struct ReadDir {
    inner: Arc<InnerReadDir>,
}

pub struct DirEntry {
    entry: abi::dirent,
    inner: Arc<InnerReadDir>,
}

#[derive(Clone, Debug)]
pub struct OpenOptions {
    // generic
    read: bool,
    write: bool,
    append: bool,
    truncate: bool,
    create: bool,
    create_new: bool,
    // system-specific
    custom_flags: i32,
}

#[derive(Copy, Clone, Debug, Default)]
pub struct FileTimes {}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FilePermissions(c_short);

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FileType(c_short);

#[derive(Debug)]
pub struct DirBuilder {}

impl FileAttr {
    pub fn size(&self) -> u64 {
        self.stat.st_size as u64
    }

    pub fn perm(&self) -> FilePermissions {
        FilePermissions(self.stat.st_mode)
    }

    pub fn file_type(&self) -> FileType {
        FileType(self.stat.st_mode)
    }

    pub fn modified(&self) -> io::Result<SystemTime> {
        Ok(SystemTime::from_time_t(self.stat.st_mtime))
    }

    pub fn accessed(&self) -> io::Result<SystemTime> {
        Ok(SystemTime::from_time_t(self.stat.st_atime))
    }

    pub fn created(&self) -> io::Result<SystemTime> {
        Ok(SystemTime::from_time_t(self.stat.st_ctime))
    }
}

impl FilePermissions {
    pub fn readonly(&self) -> bool {
        (self.0 & abi::S_IWRITE) == 0
    }

    pub fn set_readonly(&mut self, readonly: bool) {
        if readonly {
            self.0 &= !abi::S_IWRITE;
        } else {
            self.0 |= abi::S_IWRITE;
        }
    }
}

impl FileTimes {
    pub fn set_accessed(&mut self, _t: SystemTime) {}
    pub fn set_modified(&mut self, _t: SystemTime) {}
}

impl FileType {
    pub fn is_dir(&self) -> bool {
        self.is(abi::S_IFDIR)
    }
    pub fn is_file(&self) -> bool {
        self.is(abi::S_IFREG)
    }
    pub fn is_symlink(&self) -> bool {
        false
    }

    pub fn is(&self, mode: c_short) -> bool {
        self.0 & abi::S_IFMT == mode
    }
}

pub fn readdir(p: &Path) -> io::Result<ReadDir> {
    unsafe {
        let mut dir = MaybeUninit::uninit();
        error::SolidError::err_if_negative(abi::SOLID_FS_OpenDir(
            cstr(p)?.as_ptr(),
            dir.as_mut_ptr(),
        ))
        .map_err(|e| e.as_io_error())?;
        let inner = Arc::new(InnerReadDir { dirp: dir.assume_init(), root: p.to_owned() });
        Ok(ReadDir { inner })
    }
}

impl fmt::Debug for ReadDir {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
        // Thus the result will be e g 'ReadDir("/home")'
        fmt::Debug::fmt(&*self.inner.root, f)
    }
}

impl Iterator for ReadDir {
    type Item = io::Result<DirEntry>;

    fn next(&mut self) -> Option<io::Result<DirEntry>> {
        let entry = unsafe {
            let mut out_entry = MaybeUninit::uninit();
            match error::SolidError::err_if_negative(abi::SOLID_FS_ReadDir(
                self.inner.dirp,
                out_entry.as_mut_ptr(),
            )) {
                Ok(_) => out_entry.assume_init(),
                Err(e) if e.as_raw() == abi::SOLID_ERR_NOTFOUND => return None,
                Err(e) => return Some(Err(e.as_io_error())),
            }
        };

        (entry.d_name[0] != 0).then(|| Ok(DirEntry { entry, inner: Arc::clone(&self.inner) }))
    }
}

impl Drop for InnerReadDir {
    fn drop(&mut self) {
        unsafe { abi::SOLID_FS_CloseDir(self.dirp) };
    }
}

impl DirEntry {
    pub fn path(&self) -> PathBuf {
        self.inner.root.join(OsStr::from_bytes(
            unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }.to_bytes(),
        ))
    }

    pub fn file_name(&self) -> OsString {
        OsStr::from_bytes(unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }.to_bytes())
            .to_os_string()
    }

    pub fn metadata(&self) -> io::Result<FileAttr> {
        lstat(&self.path())
    }

    pub fn file_type(&self) -> io::Result<FileType> {
        match self.entry.d_type {
            abi::DT_CHR => Ok(FileType(abi::S_IFCHR)),
            abi::DT_FIFO => Ok(FileType(abi::S_IFIFO)),
            abi::DT_REG => Ok(FileType(abi::S_IFREG)),
            abi::DT_DIR => Ok(FileType(abi::S_IFDIR)),
            abi::DT_BLK => Ok(FileType(abi::S_IFBLK)),
            _ => lstat(&self.path()).map(|m| m.file_type()),
        }
    }
}

impl OpenOptions {
    pub fn new() -> OpenOptions {
        OpenOptions {
            // generic
            read: false,
            write: false,
            append: false,
            truncate: false,
            create: false,
            create_new: false,
            // system-specific
            custom_flags: 0,
        }
    }

    pub fn read(&mut self, read: bool) {
        self.read = read;
    }
    pub fn write(&mut self, write: bool) {
        self.write = write;
    }
    pub fn append(&mut self, append: bool) {
        self.append = append;
    }
    pub fn truncate(&mut self, truncate: bool) {
        self.truncate = truncate;
    }
    pub fn create(&mut self, create: bool) {
        self.create = create;
    }
    pub fn create_new(&mut self, create_new: bool) {
        self.create_new = create_new;
    }

    pub fn custom_flags(&mut self, flags: i32) {
        self.custom_flags = flags;
    }
    pub fn mode(&mut self, _mode: u32) {}

    fn get_access_mode(&self) -> io::Result<c_int> {
        match (self.read, self.write, self.append) {
            (true, false, false) => Ok(abi::O_RDONLY),
            (false, true, false) => Ok(abi::O_WRONLY),
            (true, true, false) => Ok(abi::O_RDWR),
            (false, _, true) => Ok(abi::O_WRONLY | abi::O_APPEND),
            (true, _, true) => Ok(abi::O_RDWR | abi::O_APPEND),
            (false, false, false) => Err(io::Error::from_raw_os_error(libc::EINVAL)),
        }
    }

    fn get_creation_mode(&self) -> io::Result<c_int> {
        match (self.write, self.append) {
            (true, false) => {}
            (false, false) => {
                if self.truncate || self.create || self.create_new {
                    return Err(io::Error::from_raw_os_error(libc::EINVAL));
                }
            }
            (_, true) => {
                if self.truncate && !self.create_new {
                    return Err(io::Error::from_raw_os_error(libc::EINVAL));
                }
            }
        }

        Ok(match (self.create, self.truncate, self.create_new) {
            (false, false, false) => 0,
            (true, false, false) => abi::O_CREAT,
            (false, true, false) => abi::O_TRUNC,
            (true, true, false) => abi::O_CREAT | abi::O_TRUNC,
            (_, _, true) => abi::O_CREAT | abi::O_EXCL,
        })
    }
}

fn cstr(path: &Path) -> io::Result<CString> {
    let path = path.as_os_str().as_bytes();

    if !path.starts_with(br"\") {
        // Relative paths aren't supported
        return Err(crate::io::const_error!(
            crate::io::ErrorKind::Unsupported,
            "relative path is not supported on this platform",
        ));
    }

    // Apply the thread-safety wrapper
    const SAFE_PREFIX: &[u8] = br"\TS";
    let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat();

    CString::from_vec_with_nul(wrapped_path).map_err(|_| {
        crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte")
    })
}

impl File {
    pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
        let flags = opts.get_access_mode()?
            | opts.get_creation_mode()?
            | (opts.custom_flags as c_int & !abi::O_ACCMODE);
        unsafe {
            let mut fd = MaybeUninit::uninit();
            error::SolidError::err_if_negative(abi::SOLID_FS_Open(
                fd.as_mut_ptr(),
                cstr(path)?.as_ptr(),
                flags,
            ))
            .map_err(|e| e.as_io_error())?;
            Ok(File { fd: FileDesc::new(fd.assume_init()) })
        }
    }

    pub fn file_attr(&self) -> io::Result<FileAttr> {
        unsupported()
    }

    pub fn fsync(&self) -> io::Result<()> {
        self.flush()
    }

    pub fn datasync(&self) -> io::Result<()> {
        self.flush()
    }

    pub fn lock(&self) -> io::Result<()> {
        unsupported()
    }

    pub fn lock_shared(&self) -> io::Result<()> {
        unsupported()
    }

    pub fn try_lock(&self) -> Result<(), TryLockError> {
        Err(TryLockError::Error(unsupported_err()))
    }

    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
        Err(TryLockError::Error(unsupported_err()))
    }

    pub fn unlock(&self) -> io::Result<()> {
        unsupported()
    }

    pub fn truncate(&self, _size: u64) -> io::Result<()> {
        unsupported()
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        unsafe {
            let mut out_num_bytes = MaybeUninit::uninit();
            error::SolidError::err_if_negative(abi::SOLID_FS_Read(
                self.fd.raw(),
                buf.as_mut_ptr(),
                buf.len(),
                out_num_bytes.as_mut_ptr(),
            ))
            .map_err(|e| e.as_io_error())?;
            Ok(out_num_bytes.assume_init())
        }
    }

    pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
        unsafe {
            let len = cursor.capacity();
            let mut out_num_bytes = MaybeUninit::uninit();
            error::SolidError::err_if_negative(abi::SOLID_FS_Read(
                self.fd.raw(),
                cursor.as_mut().as_mut_ptr() as *mut u8,
                len,
                out_num_bytes.as_mut_ptr(),
            ))
            .map_err(|e| e.as_io_error())?;

            // Safety: `out_num_bytes` is filled by the successful call to
            // `SOLID_FS_Read`
            let num_bytes_read = out_num_bytes.assume_init();

            // Safety: `num_bytes_read` bytes were written to the unfilled
            // portion of the buffer
            cursor.advance(num_bytes_read);

            Ok(())
        }
    }

    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
    }

    pub fn is_read_vectored(&self) -> bool {
        false
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        unsafe {
            let mut out_num_bytes = MaybeUninit::uninit();
            error::SolidError::err_if_negative(abi::SOLID_FS_Write(
                self.fd.raw(),
                buf.as_ptr(),
                buf.len(),
                out_num_bytes.as_mut_ptr(),
            ))
            .map_err(|e| e.as_io_error())?;
            Ok(out_num_bytes.assume_init())
        }
    }

    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
    }

    pub fn is_write_vectored(&self) -> bool {
        false
    }

    pub fn flush(&self) -> io::Result<()> {
        error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Sync(self.fd.raw()) })
            .map_err(|e| e.as_io_error())?;
        Ok(())
    }

    pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
        let (whence, pos) = match pos {
            // Casting to `i64` is fine, too large values will end up as
            // negative which will cause an error in `SOLID_FS_Lseek`.
            SeekFrom::Start(off) => (abi::SEEK_SET, off as i64),
            SeekFrom::End(off) => (abi::SEEK_END, off),
            SeekFrom::Current(off) => (abi::SEEK_CUR, off),
        };
        error::SolidError::err_if_negative(unsafe {
            abi::SOLID_FS_Lseek(self.fd.raw(), pos, whence)
        })
        .map_err(|e| e.as_io_error())?;
        // Get the new offset
        self.tell()
    }

    pub fn size(&self) -> Option<io::Result<u64>> {
        None
    }

    pub fn tell(&self) -> io::Result<u64> {
        unsafe {
            let mut out_offset = MaybeUninit::uninit();
            error::SolidError::err_if_negative(abi::SOLID_FS_Ftell(
                self.fd.raw(),
                out_offset.as_mut_ptr(),
            ))
            .map_err(|e| e.as_io_error())?;
            Ok(out_offset.assume_init() as u64)
        }
    }

    pub fn duplicate(&self) -> io::Result<File> {
        unsupported()
    }

    pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
        unsupported()
    }

    pub fn set_times(&self, _times: FileTimes) -> io::Result<()> {
        unsupported()
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe { abi::SOLID_FS_Close(self.fd.raw()) };
    }
}

impl DirBuilder {
    pub fn new() -> DirBuilder {
        DirBuilder {}
    }

    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
        error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Mkdir(cstr(p)?.as_ptr()) })
            .map_err(|e| e.as_io_error())?;
        Ok(())
    }
}

impl fmt::Debug for File {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("File").field("fd", &self.fd.raw()).finish()
    }
}

pub fn unlink(p: &Path) -> io::Result<()> {
    if stat(p)?.file_type().is_dir() {
        Err(io::const_error!(io::ErrorKind::IsADirectory, "is a directory"))
    } else {
        error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) })
            .map_err(|e| e.as_io_error())?;
        Ok(())
    }
}

pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
    error::SolidError::err_if_negative(unsafe {
        abi::SOLID_FS_Rename(cstr(old)?.as_ptr(), cstr(new)?.as_ptr())
    })
    .map_err(|e| e.as_io_error())?;
    Ok(())
}

pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
    error::SolidError::err_if_negative(unsafe {
        abi::SOLID_FS_Chmod(cstr(p)?.as_ptr(), perm.0.into())
    })
    .map_err(|e| e.as_io_error())?;
    Ok(())
}

pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> {
    unsupported()
}

pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> {
    unsupported()
}

pub fn rmdir(p: &Path) -> io::Result<()> {
    if stat(p)?.file_type().is_dir() {
        error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) })
            .map_err(|e| e.as_io_error())?;
        Ok(())
    } else {
        Err(io::const_error!(io::ErrorKind::NotADirectory, "not a directory"))
    }
}

pub fn remove_dir_all(path: &Path) -> io::Result<()> {
    for child in readdir(path)? {
        let result: io::Result<()> = try {
            let child = child?;
            let child_type = child.file_type()?;
            if child_type.is_dir() {
                remove_dir_all(&child.path())?;
            } else {
                unlink(&child.path())?;
            }
        };
        // ignore internal NotFound errors
        if let Err(err) = &result
            && err.kind() != io::ErrorKind::NotFound
        {
            return result;
        }
    }
    ignore_notfound(rmdir(path))
}

pub fn readlink(p: &Path) -> io::Result<PathBuf> {
    // This target doesn't support symlinks
    stat(p)?;
    Err(io::const_error!(io::ErrorKind::InvalidInput, "not a symbolic link"))
}

pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> {
    // This target doesn't support symlinks
    unsupported()
}

pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
    // This target doesn't support symlinks
    unsupported()
}

pub fn stat(p: &Path) -> io::Result<FileAttr> {
    // This target doesn't support symlinks
    lstat(p)
}

pub fn lstat(p: &Path) -> io::Result<FileAttr> {
    unsafe {
        let mut out_stat = MaybeUninit::uninit();
        error::SolidError::err_if_negative(abi::SOLID_FS_Stat(
            cstr(p)?.as_ptr(),
            out_stat.as_mut_ptr(),
        ))
        .map_err(|e| e.as_io_error())?;
        Ok(FileAttr { stat: out_stat.assume_init() })
    }
}

pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
    unsupported()
}

pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
    use crate::fs::File;

    let mut reader = File::open(from)?;
    let mut writer = File::create(to)?;

    io::copy(&mut reader, &mut writer)
}
