use std::marker;
use std::ptr;

use libc::{c_int, c_void};

use crate::util::{Binding, IntoCString};
use crate::{panic, raw, tree, Error, Oid, Repository, TreeEntry};

/// Constructor for in-memory trees
pub struct TreeBuilder<'repo> {
    raw: *mut raw::git_treebuilder,
    _marker: marker::PhantomData<&'repo Repository>,
}

impl<'repo> TreeBuilder<'repo> {
    /// Clear all the entries in the builder
    pub fn clear(&mut self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_treebuilder_clear(self.raw));
        }
        Ok(())
    }

    /// Get the number of entries
    pub fn len(&self) -> usize {
        unsafe { raw::git_treebuilder_entrycount(self.raw) as usize }
    }

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

    /// Get en entry from the builder from its filename
    pub fn get<P>(&self, filename: P) -> Result<Option<TreeEntry<'_>>, Error>
    where
        P: IntoCString,
    {
        let filename = filename.into_c_string()?;
        unsafe {
            let ret = raw::git_treebuilder_get(self.raw, filename.as_ptr());
            if ret.is_null() {
                Ok(None)
            } else {
                Ok(Some(tree::entry_from_raw_const(ret)))
            }
        }
    }

    /// Add or update an entry in the builder
    ///
    /// No attempt is made to ensure that the provided Oid points to
    /// an object of a reasonable type (or any object at all).
    ///
    /// The mode given must be one of 0o040000, 0o100644, 0o100755, 0o120000 or
    /// 0o160000 currently.
    pub fn insert<P: IntoCString>(
        &mut self,
        filename: P,
        oid: Oid,
        filemode: i32,
    ) -> Result<TreeEntry<'_>, Error> {
        let filename = filename.into_c_string()?;
        let filemode = filemode as raw::git_filemode_t;

        let mut ret = ptr::null();
        unsafe {
            try_call!(raw::git_treebuilder_insert(
                &mut ret,
                self.raw,
                filename,
                oid.raw(),
                filemode
            ));
            Ok(tree::entry_from_raw_const(ret))
        }
    }

    /// Remove an entry from the builder by its filename
    pub fn remove<P: IntoCString>(&mut self, filename: P) -> Result<(), Error> {
        let filename = filename.into_c_string()?;
        unsafe {
            try_call!(raw::git_treebuilder_remove(self.raw, filename));
        }
        Ok(())
    }

    /// Selectively remove entries from the tree
    ///
    /// Values for which the filter returns `true` will be kept.  Note
    /// that this behavior is different from the libgit2 C interface.
    pub fn filter<F>(&mut self, mut filter: F) -> Result<(), Error>
    where
        F: FnMut(&TreeEntry<'_>) -> bool,
    {
        let mut cb: &mut FilterCb<'_> = &mut filter;
        let ptr = &mut cb as *mut _;
        let cb: raw::git_treebuilder_filter_cb = Some(filter_cb);
        unsafe {
            try_call!(raw::git_treebuilder_filter(self.raw, cb, ptr as *mut _));
            panic::check();
        }
        Ok(())
    }

    /// Write the contents of the TreeBuilder as a Tree object and
    /// return its Oid
    pub fn write(&self) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_treebuilder_write(&mut raw, self.raw()));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }
}

type FilterCb<'a> = dyn FnMut(&TreeEntry<'_>) -> bool + 'a;

extern "C" fn filter_cb(entry: *const raw::git_tree_entry, payload: *mut c_void) -> c_int {
    let ret = panic::wrap(|| unsafe {
        // There's no way to return early from git_treebuilder_filter.
        if panic::panicked() {
            true
        } else {
            let entry = tree::entry_from_raw_const(entry);
            let payload = payload as *mut &mut FilterCb<'_>;
            (*payload)(&entry)
        }
    });
    if ret == Some(false) {
        1
    } else {
        0
    }
}

impl<'repo> Binding for TreeBuilder<'repo> {
    type Raw = *mut raw::git_treebuilder;

    unsafe fn from_raw(raw: *mut raw::git_treebuilder) -> TreeBuilder<'repo> {
        TreeBuilder {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *mut raw::git_treebuilder {
        self.raw
    }
}

impl<'repo> Drop for TreeBuilder<'repo> {
    fn drop(&mut self) {
        unsafe { raw::git_treebuilder_free(self.raw) }
    }
}

#[cfg(test)]
mod tests {
    use crate::ObjectType;

    #[test]
    fn smoke() {
        let (_td, repo) = crate::test::repo_init();

        let mut builder = repo.treebuilder(None).unwrap();
        assert_eq!(builder.len(), 0);
        let blob = repo.blob(b"data").unwrap();
        {
            let entry = builder.insert("a", blob, 0o100644).unwrap();
            assert_eq!(entry.kind(), Some(ObjectType::Blob));
        }
        builder.insert("b", blob, 0o100644).unwrap();
        assert_eq!(builder.len(), 2);
        builder.remove("a").unwrap();
        assert_eq!(builder.len(), 1);
        assert_eq!(builder.get("b").unwrap().unwrap().id(), blob);
        builder.clear().unwrap();
        assert_eq!(builder.len(), 0);
    }

    #[test]
    fn write() {
        let (_td, repo) = crate::test::repo_init();

        let mut builder = repo.treebuilder(None).unwrap();
        let data = repo.blob(b"data").unwrap();
        builder.insert("name", data, 0o100644).unwrap();
        let tree = builder.write().unwrap();
        let tree = repo.find_tree(tree).unwrap();
        let entry = tree.get(0).unwrap();
        assert_eq!(entry.name(), Some("name"));
        let blob = entry.to_object(&repo).unwrap();
        let blob = blob.as_blob().unwrap();
        assert_eq!(blob.content(), b"data");

        let builder = repo.treebuilder(Some(&tree)).unwrap();
        assert_eq!(builder.len(), 1);
    }

    #[test]
    fn filter() {
        let (_td, repo) = crate::test::repo_init();

        let mut builder = repo.treebuilder(None).unwrap();
        let blob = repo.blob(b"data").unwrap();
        let tree = {
            let head = repo.head().unwrap().peel(ObjectType::Commit).unwrap();
            let head = head.as_commit().unwrap();
            head.tree_id()
        };
        builder.insert("blob", blob, 0o100644).unwrap();
        builder.insert("dir", tree, 0o040000).unwrap();
        builder.insert("dir2", tree, 0o040000).unwrap();

        builder.filter(|_| true).unwrap();
        assert_eq!(builder.len(), 3);
        builder
            .filter(|e| e.kind().unwrap() != ObjectType::Blob)
            .unwrap();
        assert_eq!(builder.len(), 2);
        builder.filter(|_| false).unwrap();
        assert_eq!(builder.len(), 0);
    }
}
