use std::ffi::{CStr, CString};
use std::marker;
use std::ops::Range;
use std::path::Path;
use std::ptr;
use std::slice;

use libc::{c_char, c_int, c_uint, c_void, size_t};

use crate::util::{self, path_to_repo_path, Binding};
use crate::IntoCString;
use crate::{panic, raw, Error, IndexAddOption, IndexTime, Oid, Repository, Tree};

/// A structure to represent a git [index][1]
///
/// [1]: http://git-scm.com/book/en/Git-Internals-Git-Objects
pub struct Index {
    raw: *mut raw::git_index,
}

/// An iterator over the entries in an index
pub struct IndexEntries<'index> {
    range: Range<usize>,
    index: &'index Index,
}

/// An iterator over the conflicting entries in an index
pub struct IndexConflicts<'index> {
    conflict_iter: *mut raw::git_index_conflict_iterator,
    _marker: marker::PhantomData<&'index Index>,
}

/// A structure to represent the information returned when a conflict is detected in an index entry
pub struct IndexConflict {
    /// The ancestor index entry of the two conflicting index entries
    pub ancestor: Option<IndexEntry>,
    /// The index entry originating from the user's copy of the repository.
    /// Its contents conflict with 'their' index entry
    pub our: Option<IndexEntry>,
    /// The index entry originating from the external repository.
    /// Its contents conflict with 'our' index entry
    pub their: Option<IndexEntry>,
}

/// A callback function to filter index matches.
///
/// Used by `Index::{add_all,remove_all,update_all}`.  The first argument is the
/// path, and the second is the patchspec that matched it.  Return 0 to confirm
/// the operation on the item, > 0 to skip the item, and < 0 to abort the scan.
pub type IndexMatchedPath<'a> = dyn FnMut(&Path, &[u8]) -> i32 + 'a;

/// A structure to represent an entry or a file inside of an index.
///
/// All fields of an entry are public for modification and inspection. This is
/// also how a new index entry is created.
#[allow(missing_docs)]
#[derive(Debug)]
pub struct IndexEntry {
    pub ctime: IndexTime,
    pub mtime: IndexTime,
    pub dev: u32,
    pub ino: u32,
    pub mode: u32,
    pub uid: u32,
    pub gid: u32,
    pub file_size: u32,
    pub id: Oid,
    pub flags: u16,
    pub flags_extended: u16,

    /// The path of this index entry as a byte vector. Regardless of the
    /// current platform, the directory separator is an ASCII forward slash
    /// (`0x2F`). There are no terminating or internal NUL characters, and no
    /// trailing slashes. Most of the time, paths will be valid utf-8 — but
    /// not always. For more information on the path storage format, see
    /// [these git docs][git-index-docs]. Note that libgit2 will take care of
    /// handling the prefix compression mentioned there.
    ///
    /// [git-index-docs]: https://github.com/git/git/blob/a08a83db2bf27f015bec9a435f6d73e223c21c5e/Documentation/technical/index-format.txt#L107-L124
    ///
    /// You can turn this value into a `std::ffi::CString` with
    /// `CString::new(&entry.path[..]).unwrap()`. To turn a reference into a
    /// `&std::path::Path`, see the `bytes2path()` function in the private,
    /// internal `util` module in this crate’s source code.
    pub path: Vec<u8>,
}

impl Index {
    /// Creates a new in-memory index.
    ///
    /// This index object cannot be read/written to the filesystem, but may be
    /// used to perform in-memory index operations.
    pub fn new() -> Result<Index, Error> {
        crate::init();
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_index_new(&mut raw));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Create a new bare Git index object as a memory representation of the Git
    /// index file in 'index_path', without a repository to back it.
    ///
    /// Since there is no ODB or working directory behind this index, any Index
    /// methods which rely on these (e.g. add_path) will fail.
    ///
    /// If you need an index attached to a repository, use the `index()` method
    /// on `Repository`.
    pub fn open(index_path: &Path) -> Result<Index, Error> {
        crate::init();
        let mut raw = ptr::null_mut();
        // Normal file path OK (does not need Windows conversion).
        let index_path = index_path.into_c_string()?;
        unsafe {
            try_call!(raw::git_index_open(&mut raw, index_path));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Get index on-disk version.
    ///
    /// Valid return values are 2, 3, or 4.  If 3 is returned, an index
    /// with version 2 may be written instead, if the extension data in
    /// version 3 is not necessary.
    pub fn version(&self) -> u32 {
        unsafe { raw::git_index_version(self.raw) }
    }

    /// Set index on-disk version.
    ///
    /// Valid values are 2, 3, or 4.  If 2 is given, git_index_write may
    /// write an index with version 3 instead, if necessary to accurately
    /// represent the index.
    pub fn set_version(&mut self, version: u32) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_index_set_version(self.raw, version));
        }
        Ok(())
    }

    /// Add or update an index entry from an in-memory struct
    ///
    /// If a previous index entry exists that has the same path and stage as the
    /// given 'source_entry', it will be replaced. Otherwise, the 'source_entry'
    /// will be added.
    pub fn add(&mut self, entry: &IndexEntry) -> Result<(), Error> {
        let path = CString::new(&entry.path[..])?;

        // libgit2 encodes the length of the path in the lower bits of the
        // `flags` entry, so mask those out and recalculate here to ensure we
        // don't corrupt anything.
        let mut flags = entry.flags & !raw::GIT_INDEX_ENTRY_NAMEMASK;

        if entry.path.len() < raw::GIT_INDEX_ENTRY_NAMEMASK as usize {
            flags |= entry.path.len() as u16;
        } else {
            flags |= raw::GIT_INDEX_ENTRY_NAMEMASK;
        }

        unsafe {
            let raw = raw::git_index_entry {
                dev: entry.dev,
                ino: entry.ino,
                mode: entry.mode,
                uid: entry.uid,
                gid: entry.gid,
                file_size: entry.file_size,
                id: *entry.id.raw(),
                flags,
                flags_extended: entry.flags_extended,
                path: path.as_ptr(),
                mtime: raw::git_index_time {
                    seconds: entry.mtime.seconds(),
                    nanoseconds: entry.mtime.nanoseconds(),
                },
                ctime: raw::git_index_time {
                    seconds: entry.ctime.seconds(),
                    nanoseconds: entry.ctime.nanoseconds(),
                },
            };
            try_call!(raw::git_index_add(self.raw, &raw));
            Ok(())
        }
    }

    /// Add or update an index entry from a buffer in memory
    ///
    /// This method will create a blob in the repository that owns the index and
    /// then add the index entry to the index. The path of the entry represents
    /// the position of the blob relative to the repository's root folder.
    ///
    /// If a previous index entry exists that has the same path as the given
    /// 'entry', it will be replaced. Otherwise, the 'entry' will be added.
    /// The id and the file_size of the 'entry' are updated with the real value
    /// of the blob.
    ///
    /// This forces the file to be added to the index, not looking at gitignore
    /// rules.
    ///
    /// If this file currently is the result of a merge conflict, this file will
    /// no longer be marked as conflicting. The data about the conflict will be
    /// moved to the "resolve undo" (REUC) section.
    pub fn add_frombuffer(&mut self, entry: &IndexEntry, data: &[u8]) -> Result<(), Error> {
        let path = CString::new(&entry.path[..])?;

        // libgit2 encodes the length of the path in the lower bits of the
        // `flags` entry, so mask those out and recalculate here to ensure we
        // don't corrupt anything.
        let mut flags = entry.flags & !raw::GIT_INDEX_ENTRY_NAMEMASK;

        if entry.path.len() < raw::GIT_INDEX_ENTRY_NAMEMASK as usize {
            flags |= entry.path.len() as u16;
        } else {
            flags |= raw::GIT_INDEX_ENTRY_NAMEMASK;
        }

        unsafe {
            let raw = raw::git_index_entry {
                dev: entry.dev,
                ino: entry.ino,
                mode: entry.mode,
                uid: entry.uid,
                gid: entry.gid,
                file_size: entry.file_size,
                id: *entry.id.raw(),
                flags,
                flags_extended: entry.flags_extended,
                path: path.as_ptr(),
                mtime: raw::git_index_time {
                    seconds: entry.mtime.seconds(),
                    nanoseconds: entry.mtime.nanoseconds(),
                },
                ctime: raw::git_index_time {
                    seconds: entry.ctime.seconds(),
                    nanoseconds: entry.ctime.nanoseconds(),
                },
            };

            let ptr = data.as_ptr() as *const c_void;
            let len = data.len() as size_t;
            try_call!(raw::git_index_add_frombuffer(self.raw, &raw, ptr, len));
            Ok(())
        }
    }

    /// Add or update an index entry from a file on disk
    ///
    /// The file path must be relative to the repository's working folder and
    /// must be readable.
    ///
    /// This method will fail in bare index instances.
    ///
    /// This forces the file to be added to the index, not looking at gitignore
    /// rules.
    ///
    /// If this file currently is the result of a merge conflict, this file will
    /// no longer be marked as conflicting. The data about the conflict will be
    /// moved to the "resolve undo" (REUC) section.
    pub fn add_path(&mut self, path: &Path) -> Result<(), Error> {
        let posix_path = path_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_index_add_bypath(self.raw, posix_path));
            Ok(())
        }
    }

    /// Add or update index entries matching files in the working directory.
    ///
    /// This method will fail in bare index instances.
    ///
    /// The `pathspecs` are a list of file names or shell glob patterns that
    /// will matched against files in the repository's working directory. Each
    /// file that matches will be added to the index (either updating an
    /// existing entry or adding a new entry). You can disable glob expansion
    /// and force exact matching with the `AddDisablePathspecMatch` flag.
    ///
    /// Files that are ignored will be skipped (unlike `add_path`). If a file is
    /// already tracked in the index, then it will be updated even if it is
    /// ignored. Pass the `AddForce` flag to skip the checking of ignore rules.
    ///
    /// To emulate `git add -A` and generate an error if the pathspec contains
    /// the exact path of an ignored file (when not using `AddForce`), add the
    /// `AddCheckPathspec` flag. This checks that each entry in `pathspecs`
    /// that is an exact match to a filename on disk is either not ignored or
    /// already in the index. If this check fails, the function will return
    /// an error.
    ///
    /// To emulate `git add -A` with the "dry-run" option, just use a callback
    /// function that always returns a positive value. See below for details.
    ///
    /// If any files are currently the result of a merge conflict, those files
    /// will no longer be marked as conflicting. The data about the conflicts
    /// will be moved to the "resolve undo" (REUC) section.
    ///
    /// If you provide a callback function, it will be invoked on each matching
    /// item in the working directory immediately before it is added to /
    /// updated in the index. Returning zero will add the item to the index,
    /// greater than zero will skip the item, and less than zero will abort the
    /// scan an return an error to the caller.
    ///
    /// # Example
    ///
    /// Emulate `git add *`:
    ///
    /// ```no_run
    /// use git2::{Index, IndexAddOption, Repository};
    ///
    /// let repo = Repository::open("/path/to/a/repo").expect("failed to open");
    /// let mut index = repo.index().expect("cannot get the Index file");
    /// index.add_all(["*"].iter(), IndexAddOption::DEFAULT, None);
    /// index.write();
    /// ```
    pub fn add_all<T, I>(
        &mut self,
        pathspecs: I,
        flag: IndexAddOption,
        mut cb: Option<&mut IndexMatchedPath<'_>>,
    ) -> Result<(), Error>
    where
        T: IntoCString,
        I: IntoIterator<Item = T>,
    {
        let (_a, _b, raw_strarray) = crate::util::iter2cstrs_paths(pathspecs)?;
        let ptr = cb.as_mut();
        let callback = ptr
            .as_ref()
            .map(|_| index_matched_path_cb as extern "C" fn(_, _, _) -> _);
        unsafe {
            try_call!(raw::git_index_add_all(
                self.raw,
                &raw_strarray,
                flag.bits() as c_uint,
                callback,
                ptr.map(|p| p as *mut _).unwrap_or(ptr::null_mut()) as *mut c_void
            ));
        }
        Ok(())
    }

    /// Clear the contents (all the entries) of an index object.
    ///
    /// This clears the index object in memory; changes must be explicitly
    /// written to disk for them to take effect persistently via `write_*`.
    pub fn clear(&mut self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_index_clear(self.raw));
        }
        Ok(())
    }

    /// Get the count of entries currently in the index
    pub fn len(&self) -> usize {
        unsafe { raw::git_index_entrycount(&*self.raw) as usize }
    }

    /// Return `true` is there is no entry in the index
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Get one of the entries in the index by its position.
    pub fn get(&self, n: usize) -> Option<IndexEntry> {
        unsafe {
            let ptr = raw::git_index_get_byindex(self.raw, n as size_t);
            if ptr.is_null() {
                None
            } else {
                Some(Binding::from_raw(*ptr))
            }
        }
    }

    /// Get an iterator over the entries in this index.
    pub fn iter(&self) -> IndexEntries<'_> {
        IndexEntries {
            range: 0..self.len(),
            index: self,
        }
    }

    /// Get an iterator over the index entries that have conflicts
    pub fn conflicts(&self) -> Result<IndexConflicts<'_>, Error> {
        crate::init();
        let mut conflict_iter = ptr::null_mut();
        unsafe {
            try_call!(raw::git_index_conflict_iterator_new(
                &mut conflict_iter,
                self.raw
            ));
            Ok(Binding::from_raw(conflict_iter))
        }
    }

    /// Get one of the entries in the index by its path.
    pub fn get_path(&self, path: &Path, stage: i32) -> Option<IndexEntry> {
        let path = path_to_repo_path(path).unwrap();
        unsafe {
            let ptr = call!(raw::git_index_get_bypath(self.raw, path, stage as c_int));
            if ptr.is_null() {
                None
            } else {
                Some(Binding::from_raw(*ptr))
            }
        }
    }

    /// Does this index have conflicts?
    ///
    /// Returns `true` if the index contains conflicts, `false` if it does not.
    pub fn has_conflicts(&self) -> bool {
        unsafe { raw::git_index_has_conflicts(self.raw) == 1 }
    }

    /// Get the full path to the index file on disk.
    ///
    /// Returns `None` if this is an in-memory index.
    pub fn path(&self) -> Option<&Path> {
        unsafe { crate::opt_bytes(self, raw::git_index_path(&*self.raw)).map(util::bytes2path) }
    }

    /// Update the contents of an existing index object in memory by reading
    /// from the hard disk.
    ///
    /// If force is true, this performs a "hard" read that discards in-memory
    /// changes and always reloads the on-disk index data. If there is no
    /// on-disk version, the index will be cleared.
    ///
    /// If force is false, this does a "soft" read that reloads the index data
    /// from disk only if it has changed since the last time it was loaded.
    /// Purely in-memory index data will be untouched. Be aware: if there are
    /// changes on disk, unwritten in-memory changes are discarded.
    pub fn read(&mut self, force: bool) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_index_read(self.raw, force));
        }
        Ok(())
    }

    /// Read a tree into the index file with stats
    ///
    /// The current index contents will be replaced by the specified tree.
    pub fn read_tree(&mut self, tree: &Tree<'_>) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_index_read_tree(self.raw, &*tree.raw()));
        }
        Ok(())
    }

    /// Remove an entry from the index
    pub fn remove(&mut self, path: &Path, stage: i32) -> Result<(), Error> {
        let path = path_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_index_remove(self.raw, path, stage as c_int));
        }
        Ok(())
    }

    /// Remove an index entry corresponding to a file on disk.
    ///
    /// The file path must be relative to the repository's working folder. It
    /// may exist.
    ///
    /// If this file currently is the result of a merge conflict, this file will
    /// no longer be marked as conflicting. The data about the conflict will be
    /// moved to the "resolve undo" (REUC) section.
    pub fn remove_path(&mut self, path: &Path) -> Result<(), Error> {
        let path = path_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_index_remove_bypath(self.raw, path));
        }
        Ok(())
    }

    /// Remove all entries from the index under a given directory.
    pub fn remove_dir(&mut self, path: &Path, stage: i32) -> Result<(), Error> {
        let path = path_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_index_remove_directory(
                self.raw,
                path,
                stage as c_int
            ));
        }
        Ok(())
    }

    /// Remove all matching index entries.
    ///
    /// If you provide a callback function, it will be invoked on each matching
    /// item in the index immediately before it is removed. Return 0 to remove
    /// the item, > 0 to skip the item, and < 0 to abort the scan.
    pub fn remove_all<T, I>(
        &mut self,
        pathspecs: I,
        mut cb: Option<&mut IndexMatchedPath<'_>>,
    ) -> Result<(), Error>
    where
        T: IntoCString,
        I: IntoIterator<Item = T>,
    {
        let (_a, _b, raw_strarray) = crate::util::iter2cstrs_paths(pathspecs)?;
        let ptr = cb.as_mut();
        let callback = ptr
            .as_ref()
            .map(|_| index_matched_path_cb as extern "C" fn(_, _, _) -> _);
        unsafe {
            try_call!(raw::git_index_remove_all(
                self.raw,
                &raw_strarray,
                callback,
                ptr.map(|p| p as *mut _).unwrap_or(ptr::null_mut()) as *mut c_void
            ));
        }
        Ok(())
    }

    /// Update all index entries to match the working directory
    ///
    /// This method will fail in bare index instances.
    ///
    /// This scans the existing index entries and synchronizes them with the
    /// working directory, deleting them if the corresponding working directory
    /// file no longer exists otherwise updating the information (including
    /// adding the latest version of file to the ODB if needed).
    ///
    /// If you provide a callback function, it will be invoked on each matching
    /// item in the index immediately before it is updated (either refreshed or
    /// removed depending on working directory state). Return 0 to proceed with
    /// updating the item, > 0 to skip the item, and < 0 to abort the scan.
    pub fn update_all<T, I>(
        &mut self,
        pathspecs: I,
        mut cb: Option<&mut IndexMatchedPath<'_>>,
    ) -> Result<(), Error>
    where
        T: IntoCString,
        I: IntoIterator<Item = T>,
    {
        let (_a, _b, raw_strarray) = crate::util::iter2cstrs_paths(pathspecs)?;
        let ptr = cb.as_mut();
        let callback = ptr
            .as_ref()
            .map(|_| index_matched_path_cb as extern "C" fn(_, _, _) -> _);
        unsafe {
            try_call!(raw::git_index_update_all(
                self.raw,
                &raw_strarray,
                callback,
                ptr.map(|p| p as *mut _).unwrap_or(ptr::null_mut()) as *mut c_void
            ));
        }
        Ok(())
    }

    /// Write an existing index object from memory back to disk using an atomic
    /// file lock.
    pub fn write(&mut self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_index_write(self.raw));
        }
        Ok(())
    }

    /// Write the index as a tree.
    ///
    /// This method will scan the index and write a representation of its
    /// current state back to disk; it recursively creates tree objects for each
    /// of the subtrees stored in the index, but only returns the OID of the
    /// root tree. This is the OID that can be used e.g. to create a commit.
    ///
    /// The index instance cannot be bare, and needs to be associated to an
    /// existing repository.
    ///
    /// The index must not contain any file in conflict.
    pub fn write_tree(&mut self) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_index_write_tree(&mut raw, self.raw));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Write the index as a tree to the given repository
    ///
    /// This is the same as `write_tree` except that the destination repository
    /// can be chosen.
    pub fn write_tree_to(&mut self, repo: &Repository) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_index_write_tree_to(&mut raw, self.raw, repo.raw()));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }
}

impl Binding for Index {
    type Raw = *mut raw::git_index;
    unsafe fn from_raw(raw: *mut raw::git_index) -> Index {
        Index { raw }
    }
    fn raw(&self) -> *mut raw::git_index {
        self.raw
    }
}

impl<'index> Binding for IndexConflicts<'index> {
    type Raw = *mut raw::git_index_conflict_iterator;

    unsafe fn from_raw(raw: *mut raw::git_index_conflict_iterator) -> IndexConflicts<'index> {
        IndexConflicts {
            conflict_iter: raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *mut raw::git_index_conflict_iterator {
        self.conflict_iter
    }
}

extern "C" fn index_matched_path_cb(
    path: *const c_char,
    matched_pathspec: *const c_char,
    payload: *mut c_void,
) -> c_int {
    unsafe {
        let path = CStr::from_ptr(path).to_bytes();
        let matched_pathspec = CStr::from_ptr(matched_pathspec).to_bytes();

        panic::wrap(|| {
            let payload = payload as *mut &mut IndexMatchedPath<'_>;
            (*payload)(util::bytes2path(path), matched_pathspec) as c_int
        })
        .unwrap_or(-1)
    }
}

impl Drop for Index {
    fn drop(&mut self) {
        unsafe { raw::git_index_free(self.raw) }
    }
}

impl<'index> Drop for IndexConflicts<'index> {
    fn drop(&mut self) {
        unsafe { raw::git_index_conflict_iterator_free(self.conflict_iter) }
    }
}

impl<'index> Iterator for IndexEntries<'index> {
    type Item = IndexEntry;
    fn next(&mut self) -> Option<IndexEntry> {
        self.range.next().map(|i| self.index.get(i).unwrap())
    }
}

impl<'index> Iterator for IndexConflicts<'index> {
    type Item = Result<IndexConflict, Error>;
    fn next(&mut self) -> Option<Result<IndexConflict, Error>> {
        let mut ancestor = ptr::null();
        let mut our = ptr::null();
        let mut their = ptr::null();
        unsafe {
            try_call_iter!(raw::git_index_conflict_next(
                &mut ancestor,
                &mut our,
                &mut their,
                self.conflict_iter
            ));
            Some(Ok(IndexConflict {
                ancestor: match ancestor.is_null() {
                    false => Some(IndexEntry::from_raw(*ancestor)),
                    true => None,
                },
                our: match our.is_null() {
                    false => Some(IndexEntry::from_raw(*our)),
                    true => None,
                },
                their: match their.is_null() {
                    false => Some(IndexEntry::from_raw(*their)),
                    true => None,
                },
            }))
        }
    }
}

impl Binding for IndexEntry {
    type Raw = raw::git_index_entry;

    unsafe fn from_raw(raw: raw::git_index_entry) -> IndexEntry {
        let raw::git_index_entry {
            ctime,
            mtime,
            dev,
            ino,
            mode,
            uid,
            gid,
            file_size,
            id,
            flags,
            flags_extended,
            path,
        } = raw;

        // libgit2 encodes the length of the path in the lower bits of `flags`,
        // but if the length exceeds the number of bits then the path is
        // nul-terminated.
        let mut pathlen = (flags & raw::GIT_INDEX_ENTRY_NAMEMASK) as usize;
        if pathlen == raw::GIT_INDEX_ENTRY_NAMEMASK as usize {
            pathlen = CStr::from_ptr(path).to_bytes().len();
        }

        let path = slice::from_raw_parts(path as *const u8, pathlen);

        IndexEntry {
            dev,
            ino,
            mode,
            uid,
            gid,
            file_size,
            id: Binding::from_raw(&id as *const _),
            flags,
            flags_extended,
            path: path.to_vec(),
            mtime: Binding::from_raw(mtime),
            ctime: Binding::from_raw(ctime),
        }
    }

    fn raw(&self) -> raw::git_index_entry {
        // not implemented, may require a CString in storage
        panic!()
    }
}

#[cfg(test)]
mod tests {
    use std::fs::{self, File};
    use std::path::Path;
    use tempfile::TempDir;

    use crate::{Index, IndexEntry, IndexTime, Oid, Repository, ResetType};

    #[test]
    fn smoke() {
        let mut index = Index::new().unwrap();
        assert!(index.add_path(&Path::new(".")).is_err());
        index.clear().unwrap();
        assert_eq!(index.len(), 0);
        assert!(index.get(0).is_none());
        assert!(index.path().is_none());
        assert!(index.read(true).is_err());
    }

    #[test]
    fn smoke_from_repo() {
        let (_td, repo) = crate::test::repo_init();
        let mut index = repo.index().unwrap();
        assert_eq!(
            index.path().map(|s| s.to_path_buf()),
            Some(repo.path().join("index"))
        );
        Index::open(&repo.path().join("index")).unwrap();

        index.clear().unwrap();
        index.read(true).unwrap();
        index.write().unwrap();
        index.write_tree().unwrap();
        index.write_tree_to(&repo).unwrap();
    }

    #[test]
    fn add_all() {
        let (_td, repo) = crate::test::repo_init();
        let mut index = repo.index().unwrap();

        let root = repo.path().parent().unwrap();
        fs::create_dir(&root.join("foo")).unwrap();
        File::create(&root.join("foo/bar")).unwrap();
        let mut called = false;
        index
            .add_all(
                ["foo"].iter(),
                crate::IndexAddOption::DEFAULT,
                Some(&mut |a: &Path, b: &[u8]| {
                    assert!(!called);
                    called = true;
                    assert_eq!(b, b"foo");
                    assert_eq!(a, Path::new("foo/bar"));
                    0
                }),
            )
            .unwrap();
        assert!(called);

        called = false;
        index
            .remove_all(
                ["."].iter(),
                Some(&mut |a: &Path, b: &[u8]| {
                    assert!(!called);
                    called = true;
                    assert_eq!(b, b".");
                    assert_eq!(a, Path::new("foo/bar"));
                    0
                }),
            )
            .unwrap();
        assert!(called);
    }

    #[test]
    fn smoke_add() {
        let (_td, repo) = crate::test::repo_init();
        let mut index = repo.index().unwrap();

        let root = repo.path().parent().unwrap();
        fs::create_dir(&root.join("foo")).unwrap();
        File::create(&root.join("foo/bar")).unwrap();
        index.add_path(Path::new("foo/bar")).unwrap();
        index.write().unwrap();
        assert_eq!(index.iter().count(), 1);

        // Make sure we can use this repo somewhere else now.
        let id = index.write_tree().unwrap();
        let tree = repo.find_tree(id).unwrap();
        let sig = repo.signature().unwrap();
        let id = repo.refname_to_id("HEAD").unwrap();
        let parent = repo.find_commit(id).unwrap();
        let commit = repo
            .commit(Some("HEAD"), &sig, &sig, "commit", &tree, &[&parent])
            .unwrap();
        let obj = repo.find_object(commit, None).unwrap();
        repo.reset(&obj, ResetType::Hard, None).unwrap();

        let td2 = TempDir::new().unwrap();
        let url = crate::test::path2url(&root);
        let repo = Repository::clone(&url, td2.path()).unwrap();
        let obj = repo.find_object(commit, None).unwrap();
        repo.reset(&obj, ResetType::Hard, None).unwrap();
    }

    #[test]
    fn add_then_read() {
        let mut index = Index::new().unwrap();
        let mut e = entry();
        e.path = b"foobar".to_vec();
        index.add(&e).unwrap();
        let e = index.get(0).unwrap();
        assert_eq!(e.path.len(), 6);
    }

    #[test]
    fn add_frombuffer_then_read() {
        let (_td, repo) = crate::test::repo_init();
        let mut index = repo.index().unwrap();

        let mut e = entry();
        e.path = b"foobar".to_vec();
        let content = b"the contents";
        index.add_frombuffer(&e, content).unwrap();
        let e = index.get(0).unwrap();
        assert_eq!(e.path.len(), 6);

        let b = repo.find_blob(e.id).unwrap();
        assert_eq!(b.content(), content);
    }

    fn entry() -> IndexEntry {
        IndexEntry {
            ctime: IndexTime::new(0, 0),
            mtime: IndexTime::new(0, 0),
            dev: 0,
            ino: 0,
            mode: 0o100644,
            uid: 0,
            gid: 0,
            file_size: 0,
            id: Oid::from_bytes(&[0; 20]).unwrap(),
            flags: 0,
            flags_extended: 0,
            path: Vec::new(),
        }
    }
}
