use libc::{c_char, c_int, c_void, size_t};
use std::ffi::CString;
use std::marker;
use std::mem;
use std::ops::Range;
use std::path::Path;
use std::ptr;
use std::slice;

use crate::util::{self, Binding};
use crate::{panic, raw, Buf, Delta, DiffFormat, Error, FileMode, Oid, Repository};
use crate::{DiffFlags, DiffStatsFormat, IntoCString};

/// The diff object that contains all individual file deltas.
///
/// This is an opaque structure which will be allocated by one of the diff
/// generator functions on the `Repository` structure (e.g. `diff_tree_to_tree`
/// or other `diff_*` functions).
pub struct Diff<'repo> {
    raw: *mut raw::git_diff,
    _marker: marker::PhantomData<&'repo Repository>,
}

unsafe impl<'repo> Send for Diff<'repo> {}

/// Description of changes to one entry.
pub struct DiffDelta<'a> {
    raw: *mut raw::git_diff_delta,
    _marker: marker::PhantomData<&'a raw::git_diff_delta>,
}

/// Description of one side of a delta.
///
/// Although this is called a "file" it could represent a file, a symbolic
/// link, a submodule commit id, or even a tree (although that only happens if
/// you are tracking type changes or ignored/untracked directories).
pub struct DiffFile<'a> {
    raw: *const raw::git_diff_file,
    _marker: marker::PhantomData<&'a raw::git_diff_file>,
}

/// Structure describing options about how the diff should be executed.
pub struct DiffOptions {
    pathspec: Vec<CString>,
    pathspec_ptrs: Vec<*const c_char>,
    old_prefix: Option<CString>,
    new_prefix: Option<CString>,
    raw: raw::git_diff_options,
}

/// Control behavior of rename and copy detection
pub struct DiffFindOptions {
    raw: raw::git_diff_find_options,
}

/// Control behavior of formatting emails
pub struct DiffFormatEmailOptions {
    raw: raw::git_diff_format_email_options,
}

/// Control behavior of formatting emails
pub struct DiffPatchidOptions {
    raw: raw::git_diff_patchid_options,
}

/// An iterator over the diffs in a delta
pub struct Deltas<'diff> {
    range: Range<usize>,
    diff: &'diff Diff<'diff>,
}

/// Structure describing a line (or data span) of a diff.
pub struct DiffLine<'a> {
    raw: *const raw::git_diff_line,
    _marker: marker::PhantomData<&'a raw::git_diff_line>,
}

/// Structure describing a hunk of a diff.
pub struct DiffHunk<'a> {
    raw: *const raw::git_diff_hunk,
    _marker: marker::PhantomData<&'a raw::git_diff_hunk>,
}

/// Structure describing a hunk of a diff.
pub struct DiffStats {
    raw: *mut raw::git_diff_stats,
}

/// Structure describing the binary contents of a diff.
pub struct DiffBinary<'a> {
    raw: *const raw::git_diff_binary,
    _marker: marker::PhantomData<&'a raw::git_diff_binary>,
}

/// The contents of one of the files in a binary diff.
pub struct DiffBinaryFile<'a> {
    raw: *const raw::git_diff_binary_file,
    _marker: marker::PhantomData<&'a raw::git_diff_binary_file>,
}

/// When producing a binary diff, the binary data returned will be
/// either the deflated full ("literal") contents of the file, or
/// the deflated binary delta between the two sides (whichever is
/// smaller).
#[derive(Copy, Clone, Debug)]
pub enum DiffBinaryKind {
    /// There is no binary delta
    None,
    /// The binary data is the literal contents of the file
    Literal,
    /// The binary data is the delta from one side to the other
    Delta,
}

type PrintCb<'a> = dyn FnMut(DiffDelta<'_>, Option<DiffHunk<'_>>, DiffLine<'_>) -> bool + 'a;

pub type FileCb<'a> = dyn FnMut(DiffDelta<'_>, f32) -> bool + 'a;
pub type BinaryCb<'a> = dyn FnMut(DiffDelta<'_>, DiffBinary<'_>) -> bool + 'a;
pub type HunkCb<'a> = dyn FnMut(DiffDelta<'_>, DiffHunk<'_>) -> bool + 'a;
pub type LineCb<'a> = dyn FnMut(DiffDelta<'_>, Option<DiffHunk<'_>>, DiffLine<'_>) -> bool + 'a;

pub struct DiffCallbacks<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h> {
    pub file: Option<&'a mut FileCb<'b>>,
    pub binary: Option<&'c mut BinaryCb<'d>>,
    pub hunk: Option<&'e mut HunkCb<'f>>,
    pub line: Option<&'g mut LineCb<'h>>,
}

impl<'repo> Diff<'repo> {
    /// Merge one diff into another.
    ///
    /// This merges items from the "from" list into the "self" list.  The
    /// resulting diff will have all items that appear in either list.
    /// If an item appears in both lists, then it will be "merged" to appear
    /// as if the old version was from the "onto" list and the new version
    /// is from the "from" list (with the exception that if the item has a
    /// pending DELETE in the middle, then it will show as deleted).
    pub fn merge(&mut self, from: &Diff<'repo>) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_diff_merge(self.raw, &*from.raw));
        }
        Ok(())
    }

    /// Returns an iterator over the deltas in this diff.
    pub fn deltas(&self) -> Deltas<'_> {
        let num_deltas = unsafe { raw::git_diff_num_deltas(&*self.raw) };
        Deltas {
            range: 0..(num_deltas as usize),
            diff: self,
        }
    }

    /// Return the diff delta for an entry in the diff list.
    pub fn get_delta(&self, i: usize) -> Option<DiffDelta<'_>> {
        unsafe {
            let ptr = raw::git_diff_get_delta(&*self.raw, i as size_t);
            Binding::from_raw_opt(ptr as *mut _)
        }
    }

    /// Check if deltas are sorted case sensitively or insensitively.
    pub fn is_sorted_icase(&self) -> bool {
        unsafe { raw::git_diff_is_sorted_icase(&*self.raw) == 1 }
    }

    /// Iterate over a diff generating formatted text output.
    ///
    /// Returning `false` from the callback will terminate the iteration and
    /// return an error from this function.
    pub fn print<F>(&self, format: DiffFormat, mut cb: F) -> Result<(), Error>
    where
        F: FnMut(DiffDelta<'_>, Option<DiffHunk<'_>>, DiffLine<'_>) -> bool,
    {
        let mut cb: &mut PrintCb<'_> = &mut cb;
        let ptr = &mut cb as *mut _;
        let print: raw::git_diff_line_cb = Some(print_cb);
        unsafe {
            try_call!(raw::git_diff_print(self.raw, format, print, ptr as *mut _));
            Ok(())
        }
    }

    /// Loop over all deltas in a diff issuing callbacks.
    ///
    /// Returning `false` from any callback will terminate the iteration and
    /// return an error from this function.
    pub fn foreach(
        &self,
        file_cb: &mut FileCb<'_>,
        binary_cb: Option<&mut BinaryCb<'_>>,
        hunk_cb: Option<&mut HunkCb<'_>>,
        line_cb: Option<&mut LineCb<'_>>,
    ) -> Result<(), Error> {
        let mut cbs = DiffCallbacks {
            file: Some(file_cb),
            binary: binary_cb,
            hunk: hunk_cb,
            line: line_cb,
        };
        let ptr = &mut cbs as *mut _;
        unsafe {
            let binary_cb_c: raw::git_diff_binary_cb = if cbs.binary.is_some() {
                Some(binary_cb_c)
            } else {
                None
            };
            let hunk_cb_c: raw::git_diff_hunk_cb = if cbs.hunk.is_some() {
                Some(hunk_cb_c)
            } else {
                None
            };
            let line_cb_c: raw::git_diff_line_cb = if cbs.line.is_some() {
                Some(line_cb_c)
            } else {
                None
            };
            let file_cb: raw::git_diff_file_cb = Some(file_cb_c);
            try_call!(raw::git_diff_foreach(
                self.raw,
                file_cb,
                binary_cb_c,
                hunk_cb_c,
                line_cb_c,
                ptr as *mut _
            ));
            Ok(())
        }
    }

    /// Accumulate diff statistics for all patches.
    pub fn stats(&self) -> Result<DiffStats, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_get_stats(&mut ret, self.raw));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Transform a diff marking file renames, copies, etc.
    ///
    /// This modifies a diff in place, replacing old entries that look like
    /// renames or copies with new entries reflecting those changes. This also
    /// will, if requested, break modified files into add/remove pairs if the
    /// amount of change is above a threshold.
    pub fn find_similar(&mut self, opts: Option<&mut DiffFindOptions>) -> Result<(), Error> {
        let opts = opts.map(|opts| &opts.raw);
        unsafe {
            try_call!(raw::git_diff_find_similar(self.raw, opts));
        }
        Ok(())
    }

    /// Create an e-mail ready patch from a diff.
    ///
    /// Matches the format created by `git format-patch`
    pub fn format_email(
        &mut self,
        patch_no: usize,
        total_patches: usize,
        commit: &crate::Commit<'repo>,
        opts: Option<&mut DiffFormatEmailOptions>,
    ) -> Result<Buf, Error> {
        assert!(patch_no > 0);
        assert!(patch_no <= total_patches);
        let mut default = DiffFormatEmailOptions::default();
        let mut raw_opts = opts.map_or(&mut default.raw, |opts| &mut opts.raw);
        let summary = commit.summary_bytes().unwrap();
        let mut message = commit.message_bytes();
        assert!(message.starts_with(summary));
        message = &message[summary.len()..];
        raw_opts.patch_no = patch_no;
        raw_opts.total_patches = total_patches;
        let id = commit.id();
        raw_opts.id = id.raw();
        raw_opts.summary = summary.as_ptr() as *const _;
        raw_opts.body = message.as_ptr() as *const _;
        raw_opts.author = commit.author().raw();
        let buf = Buf::new();
        unsafe {
            try_call!(raw::git_diff_format_email(buf.raw(), self.raw, &*raw_opts));
        }
        Ok(buf)
    }

    /// Create an patchid from a diff.
    pub fn patchid(&self, opts: Option<&mut DiffPatchidOptions>) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_diff_patchid(
                &mut raw,
                self.raw,
                opts.map(|o| &mut o.raw)
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    // TODO: num_deltas_of_type, find_similar
}
impl Diff<'static> {
    /// Read the contents of a git patch file into a `git_diff` object.
    ///
    /// The diff object produced is similar to the one that would be
    /// produced if you actually produced it computationally by comparing
    /// two trees, however there may be subtle differences. For example,
    /// a patch file likely contains abbreviated object IDs, so the
    /// object IDs parsed by this function will also be abreviated.
    pub fn from_buffer(buffer: &[u8]) -> Result<Diff<'static>, Error> {
        crate::init();
        let mut diff: *mut raw::git_diff = std::ptr::null_mut();
        unsafe {
            // NOTE: Doesn't depend on repo, so lifetime can be 'static
            try_call!(raw::git_diff_from_buffer(
                &mut diff,
                buffer.as_ptr() as *const c_char,
                buffer.len()
            ));
            Ok(Diff::from_raw(diff))
        }
    }
}

pub extern "C" fn print_cb(
    delta: *const raw::git_diff_delta,
    hunk: *const raw::git_diff_hunk,
    line: *const raw::git_diff_line,
    data: *mut c_void,
) -> c_int {
    unsafe {
        let delta = Binding::from_raw(delta as *mut _);
        let hunk = Binding::from_raw_opt(hunk);
        let line = Binding::from_raw(line);

        let r = panic::wrap(|| {
            let data = data as *mut &mut PrintCb<'_>;
            (*data)(delta, hunk, line)
        });
        if r == Some(true) {
            raw::GIT_OK
        } else {
            raw::GIT_EUSER
        }
    }
}

pub extern "C" fn file_cb_c(
    delta: *const raw::git_diff_delta,
    progress: f32,
    data: *mut c_void,
) -> c_int {
    unsafe {
        let delta = Binding::from_raw(delta as *mut _);

        let r = panic::wrap(|| {
            let cbs = data as *mut DiffCallbacks<'_, '_, '_, '_, '_, '_, '_, '_>;
            match (*cbs).file {
                Some(ref mut cb) => cb(delta, progress),
                None => false,
            }
        });
        if r == Some(true) {
            raw::GIT_OK
        } else {
            raw::GIT_EUSER
        }
    }
}

pub extern "C" fn binary_cb_c(
    delta: *const raw::git_diff_delta,
    binary: *const raw::git_diff_binary,
    data: *mut c_void,
) -> c_int {
    unsafe {
        let delta = Binding::from_raw(delta as *mut _);
        let binary = Binding::from_raw(binary);

        let r = panic::wrap(|| {
            let cbs = data as *mut DiffCallbacks<'_, '_, '_, '_, '_, '_, '_, '_>;
            match (*cbs).binary {
                Some(ref mut cb) => cb(delta, binary),
                None => false,
            }
        });
        if r == Some(true) {
            raw::GIT_OK
        } else {
            raw::GIT_EUSER
        }
    }
}

pub extern "C" fn hunk_cb_c(
    delta: *const raw::git_diff_delta,
    hunk: *const raw::git_diff_hunk,
    data: *mut c_void,
) -> c_int {
    unsafe {
        let delta = Binding::from_raw(delta as *mut _);
        let hunk = Binding::from_raw(hunk);

        let r = panic::wrap(|| {
            let cbs = data as *mut DiffCallbacks<'_, '_, '_, '_, '_, '_, '_, '_>;
            match (*cbs).hunk {
                Some(ref mut cb) => cb(delta, hunk),
                None => false,
            }
        });
        if r == Some(true) {
            raw::GIT_OK
        } else {
            raw::GIT_EUSER
        }
    }
}

pub extern "C" fn line_cb_c(
    delta: *const raw::git_diff_delta,
    hunk: *const raw::git_diff_hunk,
    line: *const raw::git_diff_line,
    data: *mut c_void,
) -> c_int {
    unsafe {
        let delta = Binding::from_raw(delta as *mut _);
        let hunk = Binding::from_raw_opt(hunk);
        let line = Binding::from_raw(line);

        let r = panic::wrap(|| {
            let cbs = data as *mut DiffCallbacks<'_, '_, '_, '_, '_, '_, '_, '_>;
            match (*cbs).line {
                Some(ref mut cb) => cb(delta, hunk, line),
                None => false,
            }
        });
        if r == Some(true) {
            raw::GIT_OK
        } else {
            raw::GIT_EUSER
        }
    }
}

impl<'repo> Binding for Diff<'repo> {
    type Raw = *mut raw::git_diff;
    unsafe fn from_raw(raw: *mut raw::git_diff) -> Diff<'repo> {
        Diff {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *mut raw::git_diff {
        self.raw
    }
}

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

impl<'a> DiffDelta<'a> {
    /// Returns the flags on the delta.
    ///
    /// For more information, see `DiffFlags`'s documentation.
    pub fn flags(&self) -> DiffFlags {
        let flags = unsafe { (*self.raw).flags };
        let mut result = DiffFlags::empty();

        #[cfg(target_env = "msvc")]
        fn as_u32(flag: i32) -> u32 {
            flag as u32
        }
        #[cfg(not(target_env = "msvc"))]
        fn as_u32(flag: u32) -> u32 {
            flag
        }

        if (flags & as_u32(raw::GIT_DIFF_FLAG_BINARY)) != 0 {
            result |= DiffFlags::BINARY;
        }
        if (flags & as_u32(raw::GIT_DIFF_FLAG_NOT_BINARY)) != 0 {
            result |= DiffFlags::NOT_BINARY;
        }
        if (flags & as_u32(raw::GIT_DIFF_FLAG_VALID_ID)) != 0 {
            result |= DiffFlags::VALID_ID;
        }
        if (flags & as_u32(raw::GIT_DIFF_FLAG_EXISTS)) != 0 {
            result |= DiffFlags::EXISTS;
        }
        result
    }

    // TODO: expose when diffs are more exposed
    // pub fn similarity(&self) -> u16 {
    //     unsafe { (*self.raw).similarity }
    // }

    /// Returns the number of files in this delta.
    pub fn nfiles(&self) -> u16 {
        unsafe { (*self.raw).nfiles }
    }

    /// Returns the status of this entry
    ///
    /// For more information, see `Delta`'s documentation
    pub fn status(&self) -> Delta {
        match unsafe { (*self.raw).status } {
            raw::GIT_DELTA_UNMODIFIED => Delta::Unmodified,
            raw::GIT_DELTA_ADDED => Delta::Added,
            raw::GIT_DELTA_DELETED => Delta::Deleted,
            raw::GIT_DELTA_MODIFIED => Delta::Modified,
            raw::GIT_DELTA_RENAMED => Delta::Renamed,
            raw::GIT_DELTA_COPIED => Delta::Copied,
            raw::GIT_DELTA_IGNORED => Delta::Ignored,
            raw::GIT_DELTA_UNTRACKED => Delta::Untracked,
            raw::GIT_DELTA_TYPECHANGE => Delta::Typechange,
            raw::GIT_DELTA_UNREADABLE => Delta::Unreadable,
            raw::GIT_DELTA_CONFLICTED => Delta::Conflicted,
            n => panic!("unknown diff status: {}", n),
        }
    }

    /// Return the file which represents the "from" side of the diff.
    ///
    /// What side this means depends on the function that was used to generate
    /// the diff and will be documented on the function itself.
    pub fn old_file(&self) -> DiffFile<'a> {
        unsafe { Binding::from_raw(&(*self.raw).old_file as *const _) }
    }

    /// Return the file which represents the "to" side of the diff.
    ///
    /// What side this means depends on the function that was used to generate
    /// the diff and will be documented on the function itself.
    pub fn new_file(&self) -> DiffFile<'a> {
        unsafe { Binding::from_raw(&(*self.raw).new_file as *const _) }
    }
}

impl<'a> Binding for DiffDelta<'a> {
    type Raw = *mut raw::git_diff_delta;
    unsafe fn from_raw(raw: *mut raw::git_diff_delta) -> DiffDelta<'a> {
        DiffDelta {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *mut raw::git_diff_delta {
        self.raw
    }
}

impl<'a> std::fmt::Debug for DiffDelta<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        f.debug_struct("DiffDelta")
            .field("nfiles", &self.nfiles())
            .field("status", &self.status())
            .field("old_file", &self.old_file())
            .field("new_file", &self.new_file())
            .finish()
    }
}

impl<'a> DiffFile<'a> {
    /// Returns the Oid of this item.
    ///
    /// If this entry represents an absent side of a diff (e.g. the `old_file`
    /// of a `Added` delta), then the oid returned will be zeroes.
    pub fn id(&self) -> Oid {
        unsafe { Binding::from_raw(&(*self.raw).id as *const _) }
    }

    /// Returns the path, in bytes, of the entry relative to the working
    /// directory of the repository.
    pub fn path_bytes(&self) -> Option<&'a [u8]> {
        static FOO: () = ();
        unsafe { crate::opt_bytes(&FOO, (*self.raw).path) }
    }

    /// Returns the path of the entry relative to the working directory of the
    /// repository.
    pub fn path(&self) -> Option<&'a Path> {
        self.path_bytes().map(util::bytes2path)
    }

    /// Returns the size of this entry, in bytes
    pub fn size(&self) -> u64 {
        unsafe { (*self.raw).size as u64 }
    }

    /// Returns `true` if file(s) are treated as binary data.
    pub fn is_binary(&self) -> bool {
        unsafe { (*self.raw).flags & raw::GIT_DIFF_FLAG_BINARY as u32 != 0 }
    }

    /// Returns `true` if file(s) are treated as text data.
    pub fn is_not_binary(&self) -> bool {
        unsafe { (*self.raw).flags & raw::GIT_DIFF_FLAG_NOT_BINARY as u32 != 0 }
    }

    /// Returns `true` if `id` value is known correct.
    pub fn is_valid_id(&self) -> bool {
        unsafe { (*self.raw).flags & raw::GIT_DIFF_FLAG_VALID_ID as u32 != 0 }
    }

    /// Returns `true` if file exists at this side of the delta.
    pub fn exists(&self) -> bool {
        unsafe { (*self.raw).flags & raw::GIT_DIFF_FLAG_EXISTS as u32 != 0 }
    }

    /// Returns file mode.
    pub fn mode(&self) -> FileMode {
        match unsafe { (*self.raw).mode.into() } {
            raw::GIT_FILEMODE_UNREADABLE => FileMode::Unreadable,
            raw::GIT_FILEMODE_TREE => FileMode::Tree,
            raw::GIT_FILEMODE_BLOB => FileMode::Blob,
            raw::GIT_FILEMODE_BLOB_EXECUTABLE => FileMode::BlobExecutable,
            raw::GIT_FILEMODE_LINK => FileMode::Link,
            raw::GIT_FILEMODE_COMMIT => FileMode::Commit,
            mode => panic!("unknown mode: {}", mode),
        }
    }
}

impl<'a> Binding for DiffFile<'a> {
    type Raw = *const raw::git_diff_file;
    unsafe fn from_raw(raw: *const raw::git_diff_file) -> DiffFile<'a> {
        DiffFile {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_diff_file {
        self.raw
    }
}

impl<'a> std::fmt::Debug for DiffFile<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        let mut ds = f.debug_struct("DiffFile");
        ds.field("id", &self.id());
        if let Some(path_bytes) = &self.path_bytes() {
            ds.field("path_bytes", path_bytes);
        }
        if let Some(path) = &self.path() {
            ds.field("path", path);
        }
        ds.field("size", &self.size()).finish()
    }
}

impl Default for DiffOptions {
    fn default() -> Self {
        Self::new()
    }
}

impl DiffOptions {
    /// Creates a new set of empty diff options.
    ///
    /// All flags and other options are defaulted to false or their otherwise
    /// zero equivalents.
    pub fn new() -> DiffOptions {
        let mut opts = DiffOptions {
            pathspec: Vec::new(),
            pathspec_ptrs: Vec::new(),
            raw: unsafe { mem::zeroed() },
            old_prefix: None,
            new_prefix: None,
        };
        assert_eq!(unsafe { raw::git_diff_init_options(&mut opts.raw, 1) }, 0);
        opts
    }

    fn flag(&mut self, opt: i32, val: bool) -> &mut DiffOptions {
        let opt = opt as u32;
        if val {
            self.raw.flags |= opt;
        } else {
            self.raw.flags &= !opt;
        }
        self
    }

    /// Flag indicating whether the sides of the diff will be reversed.
    pub fn reverse(&mut self, reverse: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_REVERSE, reverse)
    }

    /// Flag indicating whether ignored files are included.
    pub fn include_ignored(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_IGNORED, include)
    }

    /// Flag indicating whether ignored directories are traversed deeply or not.
    pub fn recurse_ignored_dirs(&mut self, recurse: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_RECURSE_IGNORED_DIRS, recurse)
    }

    /// Flag indicating whether untracked files are in the diff
    pub fn include_untracked(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_UNTRACKED, include)
    }

    /// Flag indicating whether untracked directories are traversed deeply or
    /// not.
    pub fn recurse_untracked_dirs(&mut self, recurse: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_RECURSE_UNTRACKED_DIRS, recurse)
    }

    /// Flag indicating whether unmodified files are in the diff.
    pub fn include_unmodified(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_UNMODIFIED, include)
    }

    /// If enabled, then Typechange delta records are generated.
    pub fn include_typechange(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_TYPECHANGE, include)
    }

    /// Event with `include_typechange`, the tree returned generally shows a
    /// deleted blob. This flag correctly labels the tree transitions as a
    /// typechange record with the `new_file`'s mode set to tree.
    ///
    /// Note that the tree SHA will not be available.
    pub fn include_typechange_trees(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_TYPECHANGE_TREES, include)
    }

    /// Flag indicating whether file mode changes are ignored.
    pub fn ignore_filemode(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_FILEMODE, ignore)
    }

    /// Flag indicating whether all submodules should be treated as unmodified.
    pub fn ignore_submodules(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_SUBMODULES, ignore)
    }

    /// Flag indicating whether case insensitive filenames should be used.
    pub fn ignore_case(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_CASE, ignore)
    }

    /// If pathspecs are specified, this flag means that they should be applied
    /// as an exact match instead of a fnmatch pattern.
    pub fn disable_pathspec_match(&mut self, disable: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_DISABLE_PATHSPEC_MATCH, disable)
    }

    /// Disable updating the `binary` flag in delta records. This is useful when
    /// iterating over a diff if you don't need hunk and data callbacks and want
    /// to avoid having to load a file completely.
    pub fn skip_binary_check(&mut self, skip: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_SKIP_BINARY_CHECK, skip)
    }

    /// When diff finds an untracked directory, to match the behavior of core
    /// Git, it scans the contents for ignored and untracked files. If all
    /// contents are ignored, then the directory is ignored; if any contents are
    /// not ignored, then the directory is untracked. This is extra work that
    /// may not matter in many cases.
    ///
    /// This flag turns off that scan and immediately labels an untracked
    /// directory as untracked (changing the behavior to not match core git).
    pub fn enable_fast_untracked_dirs(&mut self, enable: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS, enable)
    }

    /// When diff finds a file in the working directory with stat information
    /// different from the index, but the OID ends up being the same, write the
    /// correct stat information into the index. Note: without this flag, diff
    /// will always leave the index untouched.
    pub fn update_index(&mut self, update: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_UPDATE_INDEX, update)
    }

    /// Include unreadable files in the diff
    pub fn include_unreadable(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_UNREADABLE, include)
    }

    /// Include unreadable files in the diff as untracked files
    pub fn include_unreadable_as_untracked(&mut self, include: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED, include)
    }

    /// Treat all files as text, disabling binary attributes and detection.
    pub fn force_text(&mut self, force: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_FORCE_TEXT, force)
    }

    /// Treat all files as binary, disabling text diffs
    pub fn force_binary(&mut self, force: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_FORCE_BINARY, force)
    }

    /// Ignore all whitespace
    pub fn ignore_whitespace(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_WHITESPACE, ignore)
    }

    /// Ignore changes in the amount of whitespace
    pub fn ignore_whitespace_change(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_WHITESPACE_CHANGE, ignore)
    }

    /// Ignore whitespace at the end of line
    pub fn ignore_whitespace_eol(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_WHITESPACE_EOL, ignore)
    }

    /// Ignore blank lines
    pub fn ignore_blank_lines(&mut self, ignore: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_IGNORE_BLANK_LINES, ignore)
    }

    /// When generating patch text, include the content of untracked files.
    ///
    /// This automatically turns on `include_untracked` but it does not turn on
    /// `recurse_untracked_dirs`. Add that flag if you want the content of every
    /// single untracked file.
    pub fn show_untracked_content(&mut self, show: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_SHOW_UNTRACKED_CONTENT, show)
    }

    /// When generating output, include the names of unmodified files if they
    /// are included in the `Diff`. Normally these are skipped in the formats
    /// that list files (e.g. name-only, name-status, raw). Even with this these
    /// will not be included in the patch format.
    pub fn show_unmodified(&mut self, show: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_SHOW_UNMODIFIED, show)
    }

    /// Use the "patience diff" algorithm
    pub fn patience(&mut self, patience: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_PATIENCE, patience)
    }

    /// Take extra time to find the minimal diff
    pub fn minimal(&mut self, minimal: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_MINIMAL, minimal)
    }

    /// Include the necessary deflate/delta information so that `git-apply` can
    /// apply given diff information to binary files.
    pub fn show_binary(&mut self, show: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_SHOW_BINARY, show)
    }

    /// Use a heuristic that takes indentation and whitespace into account
    /// which generally can produce better diffs when dealing with ambiguous
    /// diff hunks.
    pub fn indent_heuristic(&mut self, heuristic: bool) -> &mut DiffOptions {
        self.flag(raw::GIT_DIFF_INDENT_HEURISTIC, heuristic)
    }

    /// Set the number of unchanged lines that define the boundary of a hunk
    /// (and to display before and after).
    ///
    /// The default value for this is 3.
    pub fn context_lines(&mut self, lines: u32) -> &mut DiffOptions {
        self.raw.context_lines = lines;
        self
    }

    /// Set the maximum number of unchanged lines between hunk boundaries before
    /// the hunks will be merged into one.
    ///
    /// The default value for this is 0.
    pub fn interhunk_lines(&mut self, lines: u32) -> &mut DiffOptions {
        self.raw.interhunk_lines = lines;
        self
    }

    /// The default value for this is `core.abbrev` or 7 if unset.
    pub fn id_abbrev(&mut self, abbrev: u16) -> &mut DiffOptions {
        self.raw.id_abbrev = abbrev;
        self
    }

    /// Maximum size (in bytes) above which a blob will be marked as binary
    /// automatically.
    ///
    /// A negative value will disable this entirely.
    ///
    /// The default value for this is 512MB.
    pub fn max_size(&mut self, size: i64) -> &mut DiffOptions {
        self.raw.max_size = size as raw::git_off_t;
        self
    }

    /// The virtual "directory" to prefix old file names with in hunk headers.
    ///
    /// The default value for this is "a".
    pub fn old_prefix<T: IntoCString>(&mut self, t: T) -> &mut DiffOptions {
        self.old_prefix = Some(t.into_c_string().unwrap());
        self
    }

    /// The virtual "directory" to prefix new file names with in hunk headers.
    ///
    /// The default value for this is "b".
    pub fn new_prefix<T: IntoCString>(&mut self, t: T) -> &mut DiffOptions {
        self.new_prefix = Some(t.into_c_string().unwrap());
        self
    }

    /// Add to the array of paths/fnmatch patterns to constrain the diff.
    pub fn pathspec<T: IntoCString>(&mut self, pathspec: T) -> &mut DiffOptions {
        let s = util::cstring_to_repo_path(pathspec).unwrap();
        self.pathspec_ptrs.push(s.as_ptr());
        self.pathspec.push(s);
        self
    }

    /// Acquire a pointer to the underlying raw options.
    ///
    /// This function is unsafe as the pointer is only valid so long as this
    /// structure is not moved, modified, or used elsewhere.
    pub unsafe fn raw(&mut self) -> *const raw::git_diff_options {
        self.raw.old_prefix = self
            .old_prefix
            .as_ref()
            .map(|s| s.as_ptr())
            .unwrap_or(ptr::null());
        self.raw.new_prefix = self
            .new_prefix
            .as_ref()
            .map(|s| s.as_ptr())
            .unwrap_or(ptr::null());
        self.raw.pathspec.count = self.pathspec_ptrs.len() as size_t;
        self.raw.pathspec.strings = self.pathspec_ptrs.as_ptr() as *mut _;
        &self.raw as *const _
    }

    // TODO: expose ignore_submodules, notify_cb/notify_payload
}

impl<'diff> Iterator for Deltas<'diff> {
    type Item = DiffDelta<'diff>;
    fn next(&mut self) -> Option<DiffDelta<'diff>> {
        self.range.next().and_then(|i| self.diff.get_delta(i))
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.range.size_hint()
    }
}
impl<'diff> DoubleEndedIterator for Deltas<'diff> {
    fn next_back(&mut self) -> Option<DiffDelta<'diff>> {
        self.range.next_back().and_then(|i| self.diff.get_delta(i))
    }
}
impl<'diff> ExactSizeIterator for Deltas<'diff> {}

/// Line origin constants.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DiffLineType {
    /// These values will be sent to `git_diff_line_cb` along with the line
    Context,
    ///
    Addition,
    ///
    Deletion,
    /// Both files have no LF at end
    ContextEOFNL,
    /// Old has no LF at end, new does
    AddEOFNL,
    /// Old has LF at end, new does not
    DeleteEOFNL,
    /// The following values will only be sent to a `git_diff_line_cb` when
    /// the content of a diff is being formatted through `git_diff_print`.
    FileHeader,
    ///
    HunkHeader,
    /// For "Binary files x and y differ"
    Binary,
}

impl Binding for DiffLineType {
    type Raw = raw::git_diff_line_t;
    unsafe fn from_raw(raw: raw::git_diff_line_t) -> Self {
        match raw {
            raw::GIT_DIFF_LINE_CONTEXT => DiffLineType::Context,
            raw::GIT_DIFF_LINE_ADDITION => DiffLineType::Addition,
            raw::GIT_DIFF_LINE_DELETION => DiffLineType::Deletion,
            raw::GIT_DIFF_LINE_CONTEXT_EOFNL => DiffLineType::ContextEOFNL,
            raw::GIT_DIFF_LINE_ADD_EOFNL => DiffLineType::AddEOFNL,
            raw::GIT_DIFF_LINE_DEL_EOFNL => DiffLineType::DeleteEOFNL,
            raw::GIT_DIFF_LINE_FILE_HDR => DiffLineType::FileHeader,
            raw::GIT_DIFF_LINE_HUNK_HDR => DiffLineType::HunkHeader,
            raw::GIT_DIFF_LINE_BINARY => DiffLineType::Binary,
            _ => panic!("Unknown git diff line type"),
        }
    }
    fn raw(&self) -> raw::git_diff_line_t {
        match *self {
            DiffLineType::Context => raw::GIT_DIFF_LINE_CONTEXT,
            DiffLineType::Addition => raw::GIT_DIFF_LINE_ADDITION,
            DiffLineType::Deletion => raw::GIT_DIFF_LINE_DELETION,
            DiffLineType::ContextEOFNL => raw::GIT_DIFF_LINE_CONTEXT_EOFNL,
            DiffLineType::AddEOFNL => raw::GIT_DIFF_LINE_ADD_EOFNL,
            DiffLineType::DeleteEOFNL => raw::GIT_DIFF_LINE_DEL_EOFNL,
            DiffLineType::FileHeader => raw::GIT_DIFF_LINE_FILE_HDR,
            DiffLineType::HunkHeader => raw::GIT_DIFF_LINE_HUNK_HDR,
            DiffLineType::Binary => raw::GIT_DIFF_LINE_BINARY,
        }
    }
}

impl<'a> DiffLine<'a> {
    /// Line number in old file or `None` for added line
    pub fn old_lineno(&self) -> Option<u32> {
        match unsafe { (*self.raw).old_lineno } {
            n if n < 0 => None,
            n => Some(n as u32),
        }
    }

    /// Line number in new file or `None` for deleted line
    pub fn new_lineno(&self) -> Option<u32> {
        match unsafe { (*self.raw).new_lineno } {
            n if n < 0 => None,
            n => Some(n as u32),
        }
    }

    /// Number of newline characters in content
    pub fn num_lines(&self) -> u32 {
        unsafe { (*self.raw).num_lines as u32 }
    }

    /// Offset in the original file to the content
    pub fn content_offset(&self) -> i64 {
        unsafe { (*self.raw).content_offset as i64 }
    }

    /// Content of this line as bytes.
    pub fn content(&self) -> &'a [u8] {
        unsafe {
            slice::from_raw_parts(
                (*self.raw).content as *const u8,
                (*self.raw).content_len as usize,
            )
        }
    }

    /// origin of this `DiffLine`.
    ///
    pub fn origin_value(&self) -> DiffLineType {
        unsafe { Binding::from_raw((*self.raw).origin as raw::git_diff_line_t) }
    }

    /// Sigil showing the origin of this `DiffLine`.
    ///
    ///  * ` ` - Line context
    ///  * `+` - Line addition
    ///  * `-` - Line deletion
    ///  * `=` - Context (End of file)
    ///  * `>` - Add (End of file)
    ///  * `<` - Remove (End of file)
    ///  * `F` - File header
    ///  * `H` - Hunk header
    ///  * `B` - Line binary
    pub fn origin(&self) -> char {
        match unsafe { (*self.raw).origin as raw::git_diff_line_t } {
            raw::GIT_DIFF_LINE_CONTEXT => ' ',
            raw::GIT_DIFF_LINE_ADDITION => '+',
            raw::GIT_DIFF_LINE_DELETION => '-',
            raw::GIT_DIFF_LINE_CONTEXT_EOFNL => '=',
            raw::GIT_DIFF_LINE_ADD_EOFNL => '>',
            raw::GIT_DIFF_LINE_DEL_EOFNL => '<',
            raw::GIT_DIFF_LINE_FILE_HDR => 'F',
            raw::GIT_DIFF_LINE_HUNK_HDR => 'H',
            raw::GIT_DIFF_LINE_BINARY => 'B',
            _ => ' ',
        }
    }
}

impl<'a> Binding for DiffLine<'a> {
    type Raw = *const raw::git_diff_line;
    unsafe fn from_raw(raw: *const raw::git_diff_line) -> DiffLine<'a> {
        DiffLine {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_diff_line {
        self.raw
    }
}

impl<'a> std::fmt::Debug for DiffLine<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        let mut ds = f.debug_struct("DiffLine");
        if let Some(old_lineno) = &self.old_lineno() {
            ds.field("old_lineno", old_lineno);
        }
        if let Some(new_lineno) = &self.new_lineno() {
            ds.field("new_lineno", new_lineno);
        }
        ds.field("num_lines", &self.num_lines())
            .field("content_offset", &self.content_offset())
            .field("content", &self.content())
            .field("origin", &self.origin())
            .finish()
    }
}

impl<'a> DiffHunk<'a> {
    /// Starting line number in old_file
    pub fn old_start(&self) -> u32 {
        unsafe { (*self.raw).old_start as u32 }
    }

    /// Number of lines in old_file
    pub fn old_lines(&self) -> u32 {
        unsafe { (*self.raw).old_lines as u32 }
    }

    /// Starting line number in new_file
    pub fn new_start(&self) -> u32 {
        unsafe { (*self.raw).new_start as u32 }
    }

    /// Number of lines in new_file
    pub fn new_lines(&self) -> u32 {
        unsafe { (*self.raw).new_lines as u32 }
    }

    /// Header text
    pub fn header(&self) -> &'a [u8] {
        unsafe {
            slice::from_raw_parts(
                (*self.raw).header.as_ptr() as *const u8,
                (*self.raw).header_len as usize,
            )
        }
    }
}

impl<'a> Binding for DiffHunk<'a> {
    type Raw = *const raw::git_diff_hunk;
    unsafe fn from_raw(raw: *const raw::git_diff_hunk) -> DiffHunk<'a> {
        DiffHunk {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_diff_hunk {
        self.raw
    }
}

impl<'a> std::fmt::Debug for DiffHunk<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        f.debug_struct("DiffHunk")
            .field("old_start", &self.old_start())
            .field("old_lines", &self.old_lines())
            .field("new_start", &self.new_start())
            .field("new_lines", &self.new_lines())
            .field("header", &self.header())
            .finish()
    }
}

impl DiffStats {
    /// Get the total number of files changed in a diff.
    pub fn files_changed(&self) -> usize {
        unsafe { raw::git_diff_stats_files_changed(&*self.raw) as usize }
    }

    /// Get the total number of insertions in a diff
    pub fn insertions(&self) -> usize {
        unsafe { raw::git_diff_stats_insertions(&*self.raw) as usize }
    }

    /// Get the total number of deletions in a diff
    pub fn deletions(&self) -> usize {
        unsafe { raw::git_diff_stats_deletions(&*self.raw) as usize }
    }

    /// Print diff statistics to a Buf
    pub fn to_buf(&self, format: DiffStatsFormat, width: usize) -> Result<Buf, Error> {
        let buf = Buf::new();
        unsafe {
            try_call!(raw::git_diff_stats_to_buf(
                buf.raw(),
                self.raw,
                format.bits(),
                width as size_t
            ));
        }
        Ok(buf)
    }
}

impl Binding for DiffStats {
    type Raw = *mut raw::git_diff_stats;

    unsafe fn from_raw(raw: *mut raw::git_diff_stats) -> DiffStats {
        DiffStats { raw }
    }
    fn raw(&self) -> *mut raw::git_diff_stats {
        self.raw
    }
}

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

impl std::fmt::Debug for DiffStats {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        f.debug_struct("DiffStats")
            .field("files_changed", &self.files_changed())
            .field("insertions", &self.insertions())
            .field("deletions", &self.deletions())
            .finish()
    }
}

impl<'a> DiffBinary<'a> {
    /// Returns whether there is data in this binary structure or not.
    ///
    /// If this is `true`, then this was produced and included binary content.
    /// If this is `false` then this was generated knowing only that a binary
    /// file changed but without providing the data, probably from a patch that
    /// said `Binary files a/file.txt and b/file.txt differ`.
    pub fn contains_data(&self) -> bool {
        unsafe { (*self.raw).contains_data == 1 }
    }

    /// The contents of the old file.
    pub fn old_file(&self) -> DiffBinaryFile<'a> {
        unsafe { Binding::from_raw(&(*self.raw).old_file as *const _) }
    }

    /// The contents of the new file.
    pub fn new_file(&self) -> DiffBinaryFile<'a> {
        unsafe { Binding::from_raw(&(*self.raw).new_file as *const _) }
    }
}

impl<'a> Binding for DiffBinary<'a> {
    type Raw = *const raw::git_diff_binary;
    unsafe fn from_raw(raw: *const raw::git_diff_binary) -> DiffBinary<'a> {
        DiffBinary {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_diff_binary {
        self.raw
    }
}

impl<'a> DiffBinaryFile<'a> {
    /// The type of binary data for this file
    pub fn kind(&self) -> DiffBinaryKind {
        unsafe { Binding::from_raw((*self.raw).kind) }
    }

    /// The binary data, deflated
    pub fn data(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts((*self.raw).data as *const u8, (*self.raw).datalen as usize)
        }
    }

    /// The length of the binary data after inflation
    pub fn inflated_len(&self) -> usize {
        unsafe { (*self.raw).inflatedlen as usize }
    }
}

impl<'a> Binding for DiffBinaryFile<'a> {
    type Raw = *const raw::git_diff_binary_file;
    unsafe fn from_raw(raw: *const raw::git_diff_binary_file) -> DiffBinaryFile<'a> {
        DiffBinaryFile {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_diff_binary_file {
        self.raw
    }
}

impl Binding for DiffBinaryKind {
    type Raw = raw::git_diff_binary_t;
    unsafe fn from_raw(raw: raw::git_diff_binary_t) -> DiffBinaryKind {
        match raw {
            raw::GIT_DIFF_BINARY_NONE => DiffBinaryKind::None,
            raw::GIT_DIFF_BINARY_LITERAL => DiffBinaryKind::Literal,
            raw::GIT_DIFF_BINARY_DELTA => DiffBinaryKind::Delta,
            _ => panic!("Unknown git diff binary kind"),
        }
    }
    fn raw(&self) -> raw::git_diff_binary_t {
        match *self {
            DiffBinaryKind::None => raw::GIT_DIFF_BINARY_NONE,
            DiffBinaryKind::Literal => raw::GIT_DIFF_BINARY_LITERAL,
            DiffBinaryKind::Delta => raw::GIT_DIFF_BINARY_DELTA,
        }
    }
}

impl Default for DiffFindOptions {
    fn default() -> Self {
        Self::new()
    }
}

impl DiffFindOptions {
    /// Creates a new set of empty diff find options.
    ///
    /// All flags and other options are defaulted to false or their otherwise
    /// zero equivalents.
    pub fn new() -> DiffFindOptions {
        let mut opts = DiffFindOptions {
            raw: unsafe { mem::zeroed() },
        };
        assert_eq!(
            unsafe { raw::git_diff_find_init_options(&mut opts.raw, 1) },
            0
        );
        opts
    }

    fn flag(&mut self, opt: u32, val: bool) -> &mut DiffFindOptions {
        if val {
            self.raw.flags |= opt;
        } else {
            self.raw.flags &= !opt;
        }
        self
    }

    /// Reset all flags back to their unset state, indicating that
    /// `diff.renames` should be used instead. This is overridden once any flag
    /// is set.
    pub fn by_config(&mut self) -> &mut DiffFindOptions {
        self.flag(0xffffffff, false)
    }

    /// Look for renames?
    pub fn renames(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_RENAMES, find)
    }

    /// Consider old side of modified for renames?
    pub fn renames_from_rewrites(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_RENAMES_FROM_REWRITES, find)
    }

    /// Look for copies?
    pub fn copies(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_COPIES, find)
    }

    /// Consider unmodified as copy sources?
    ///
    /// For this to work correctly, use `include_unmodified` when the initial
    /// diff is being generated.
    pub fn copies_from_unmodified(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED, find)
    }

    /// Mark significant rewrites for split.
    pub fn rewrites(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_REWRITES, find)
    }

    /// Actually split large rewrites into delete/add pairs
    pub fn break_rewrites(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_BREAK_REWRITES, find)
    }

    #[doc(hidden)]
    pub fn break_rewries(&mut self, find: bool) -> &mut DiffFindOptions {
        self.break_rewrites(find)
    }

    /// Find renames/copies for untracked items in working directory.
    ///
    /// For this to work correctly use the `include_untracked` option when the
    /// initial diff is being generated.
    pub fn for_untracked(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_FOR_UNTRACKED, find)
    }

    /// Turn on all finding features.
    pub fn all(&mut self, find: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_ALL, find)
    }

    /// Measure similarity ignoring leading whitespace (default)
    pub fn ignore_leading_whitespace(&mut self, ignore: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE, ignore)
    }

    /// Measure similarity ignoring all whitespace
    pub fn ignore_whitespace(&mut self, ignore: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_IGNORE_WHITESPACE, ignore)
    }

    /// Measure similarity including all data
    pub fn dont_ignore_whitespace(&mut self, dont: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE, dont)
    }

    /// Measure similarity only by comparing SHAs (fast and cheap)
    pub fn exact_match_only(&mut self, exact: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_EXACT_MATCH_ONLY, exact)
    }

    /// Do not break rewrites unless they contribute to a rename.
    ///
    /// Normally, `break_rewrites` and `rewrites` will measure the
    /// self-similarity of modified files and split the ones that have changed a
    /// lot into a delete/add pair.  Then the sides of that pair will be
    /// considered candidates for rename and copy detection
    ///
    /// If you add this flag in and the split pair is not used for an actual
    /// rename or copy, then the modified record will be restored to a regular
    /// modified record instead of being split.
    pub fn break_rewrites_for_renames_only(&mut self, b: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY, b)
    }

    /// Remove any unmodified deltas after find_similar is done.
    ///
    /// Using `copies_from_unmodified` to emulate the `--find-copies-harder`
    /// behavior requires building a diff with the `include_unmodified` flag. If
    /// you do not want unmodified records in the final result, pas this flag to
    /// have them removed.
    pub fn remove_unmodified(&mut self, remove: bool) -> &mut DiffFindOptions {
        self.flag(raw::GIT_DIFF_FIND_REMOVE_UNMODIFIED, remove)
    }

    /// Similarity to consider a file renamed (default 50)
    pub fn rename_threshold(&mut self, thresh: u16) -> &mut DiffFindOptions {
        self.raw.rename_threshold = thresh;
        self
    }

    /// Similarity of modified to be eligible rename source (default 50)
    pub fn rename_from_rewrite_threshold(&mut self, thresh: u16) -> &mut DiffFindOptions {
        self.raw.rename_from_rewrite_threshold = thresh;
        self
    }

    /// Similarity to consider a file copy (default 50)
    pub fn copy_threshold(&mut self, thresh: u16) -> &mut DiffFindOptions {
        self.raw.copy_threshold = thresh;
        self
    }

    /// Similarity to split modify into delete/add pair (default 60)
    pub fn break_rewrite_threshold(&mut self, thresh: u16) -> &mut DiffFindOptions {
        self.raw.break_rewrite_threshold = thresh;
        self
    }

    /// Maximum similarity sources to examine for a file (somewhat like
    /// git-diff's `-l` option or `diff.renameLimit` config)
    ///
    /// Defaults to 200
    pub fn rename_limit(&mut self, limit: usize) -> &mut DiffFindOptions {
        self.raw.rename_limit = limit as size_t;
        self
    }

    // TODO: expose git_diff_similarity_metric
}

impl Default for DiffFormatEmailOptions {
    fn default() -> Self {
        Self::new()
    }
}

impl DiffFormatEmailOptions {
    /// Creates a new set of email options,
    /// initialized to the default values
    pub fn new() -> Self {
        let mut opts = DiffFormatEmailOptions {
            raw: unsafe { mem::zeroed() },
        };
        assert_eq!(
            unsafe { raw::git_diff_format_email_options_init(&mut opts.raw, 1) },
            0
        );
        opts
    }

    fn flag(&mut self, opt: u32, val: bool) -> &mut Self {
        if val {
            self.raw.flags |= opt;
        } else {
            self.raw.flags &= !opt;
        }
        self
    }

    /// Exclude `[PATCH]` from the subject header
    pub fn exclude_subject_patch_header(&mut self, should_exclude: bool) -> &mut Self {
        self.flag(
            raw::GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER,
            should_exclude,
        )
    }
}

impl DiffPatchidOptions {
    /// Creates a new set of patchid options,
    /// initialized to the default values
    pub fn new() -> Self {
        let mut opts = DiffPatchidOptions {
            raw: unsafe { mem::zeroed() },
        };
        assert_eq!(
            unsafe {
                raw::git_diff_patchid_options_init(
                    &mut opts.raw,
                    raw::GIT_DIFF_PATCHID_OPTIONS_VERSION,
                )
            },
            0
        );
        opts
    }
}

#[cfg(test)]
mod tests {
    use crate::{DiffLineType, DiffOptions, Oid, Signature, Time};
    use std::borrow::Borrow;
    use std::fs::File;
    use std::io::Write;
    use std::path::Path;

    #[test]
    fn smoke() {
        let (_td, repo) = crate::test::repo_init();
        let diff = repo.diff_tree_to_workdir(None, None).unwrap();
        assert_eq!(diff.deltas().len(), 0);
        let stats = diff.stats().unwrap();
        assert_eq!(stats.insertions(), 0);
        assert_eq!(stats.deletions(), 0);
        assert_eq!(stats.files_changed(), 0);
        let patchid = diff.patchid(None).unwrap();
        assert_ne!(patchid, Oid::zero());
    }

    #[test]
    fn foreach_smoke() {
        let (_td, repo) = crate::test::repo_init();
        let diff = t!(repo.diff_tree_to_workdir(None, None));
        let mut count = 0;
        t!(diff.foreach(
            &mut |_file, _progress| {
                count = count + 1;
                true
            },
            None,
            None,
            None
        ));
        assert_eq!(count, 0);
    }

    #[test]
    fn foreach_file_only() {
        let path = Path::new("foo");
        let (td, repo) = crate::test::repo_init();
        t!(t!(File::create(&td.path().join(path))).write_all(b"bar"));
        let mut opts = DiffOptions::new();
        opts.include_untracked(true);
        let diff = t!(repo.diff_tree_to_workdir(None, Some(&mut opts)));
        let mut count = 0;
        let mut result = None;
        t!(diff.foreach(
            &mut |file, _progress| {
                count = count + 1;
                result = file.new_file().path().map(ToOwned::to_owned);
                true
            },
            None,
            None,
            None
        ));
        assert_eq!(result.as_ref().map(Borrow::borrow), Some(path));
        assert_eq!(count, 1);
    }

    #[test]
    fn foreach_file_and_hunk() {
        let path = Path::new("foo");
        let (td, repo) = crate::test::repo_init();
        t!(t!(File::create(&td.path().join(path))).write_all(b"bar"));
        let mut index = t!(repo.index());
        t!(index.add_path(path));
        let mut opts = DiffOptions::new();
        opts.include_untracked(true);
        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));
        let mut new_lines = 0;
        t!(diff.foreach(
            &mut |_file, _progress| { true },
            None,
            Some(&mut |_file, hunk| {
                new_lines = hunk.new_lines();
                true
            }),
            None
        ));
        assert_eq!(new_lines, 1);
    }

    #[test]
    fn foreach_all_callbacks() {
        let fib = vec![0, 1, 1, 2, 3, 5, 8];
        // Verified with a node implementation of deflate, might be worth
        // adding a deflate lib to do this inline here.
        let deflated_fib = vec![120, 156, 99, 96, 100, 100, 98, 102, 229, 0, 0, 0, 53, 0, 21];
        let foo_path = Path::new("foo");
        let bin_path = Path::new("bin");
        let (td, repo) = crate::test::repo_init();
        t!(t!(File::create(&td.path().join(foo_path))).write_all(b"bar\n"));
        t!(t!(File::create(&td.path().join(bin_path))).write_all(&fib));
        let mut index = t!(repo.index());
        t!(index.add_path(foo_path));
        t!(index.add_path(bin_path));
        let mut opts = DiffOptions::new();
        opts.include_untracked(true).show_binary(true);
        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));
        let mut bin_content = None;
        let mut new_lines = 0;
        let mut line_content = None;
        t!(diff.foreach(
            &mut |_file, _progress| { true },
            Some(&mut |_file, binary| {
                bin_content = Some(binary.new_file().data().to_owned());
                true
            }),
            Some(&mut |_file, hunk| {
                new_lines = hunk.new_lines();
                true
            }),
            Some(&mut |_file, _hunk, line| {
                line_content = String::from_utf8(line.content().into()).ok();
                true
            })
        ));
        assert_eq!(bin_content, Some(deflated_fib));
        assert_eq!(new_lines, 1);
        assert_eq!(line_content, Some("bar\n".to_string()));
    }

    #[test]
    fn format_email_simple() {
        let (_td, repo) = crate::test::repo_init();
        const COMMIT_MESSAGE: &str = "Modify some content";
        const EXPECTED_EMAIL_START: &str = concat!(
            "From f1234fb0588b6ed670779a34ba5c51ef962f285f Mon Sep 17 00:00:00 2001\n",
            "From: Techcable <dummy@dummy.org>\n",
            "Date: Tue, 11 Jan 1972 17:46:40 +0000\n",
            "Subject: [PATCH] Modify some content\n",
            "\n",
            "---\n",
            " file1.txt | 8 +++++---\n",
            " 1 file changed, 5 insertions(+), 3 deletions(-)\n",
            "\n",
            "diff --git a/file1.txt b/file1.txt\n",
            "index 94aaae8..af8f41d 100644\n",
            "--- a/file1.txt\n",
            "+++ b/file1.txt\n",
            "@@ -1,15 +1,17 @@\n",
            " file1.txt\n",
            " file1.txt\n",
            "+_file1.txt_\n",
            " file1.txt\n",
            " file1.txt\n",
            " file1.txt\n",
            " file1.txt\n",
            "+\n",
            "+\n",
            " file1.txt\n",
            " file1.txt\n",
            " file1.txt\n",
            " file1.txt\n",
            " file1.txt\n",
            "-file1.txt\n",
            "-file1.txt\n",
            "-file1.txt\n",
            "+_file1.txt_\n",
            "+_file1.txt_\n",
            " file1.txt\n",
            "--\n"
        );
        const ORIGINAL_FILE: &str = concat!(
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n"
        );
        const UPDATED_FILE: &str = concat!(
            "file1.txt\n",
            "file1.txt\n",
            "_file1.txt_\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "\n",
            "\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "file1.txt\n",
            "_file1.txt_\n",
            "_file1.txt_\n",
            "file1.txt\n"
        );
        const FILE_MODE: i32 = 0o100644;
        let original_file = repo.blob(ORIGINAL_FILE.as_bytes()).unwrap();
        let updated_file = repo.blob(UPDATED_FILE.as_bytes()).unwrap();
        let mut original_tree = repo.treebuilder(None).unwrap();
        original_tree
            .insert("file1.txt", original_file, FILE_MODE)
            .unwrap();
        let original_tree = original_tree.write().unwrap();
        let mut updated_tree = repo.treebuilder(None).unwrap();
        updated_tree
            .insert("file1.txt", updated_file, FILE_MODE)
            .unwrap();
        let updated_tree = updated_tree.write().unwrap();
        let time = Time::new(64_000_000, 0);
        let author = Signature::new("Techcable", "dummy@dummy.org", &time).unwrap();
        let updated_commit = repo
            .commit(
                None,
                &author,
                &author,
                COMMIT_MESSAGE,
                &repo.find_tree(updated_tree).unwrap(),
                &[], // NOTE: Have no parents to ensure stable hash
            )
            .unwrap();
        let updated_commit = repo.find_commit(updated_commit).unwrap();
        let mut diff = repo
            .diff_tree_to_tree(
                Some(&repo.find_tree(original_tree).unwrap()),
                Some(&repo.find_tree(updated_tree).unwrap()),
                None,
            )
            .unwrap();
        let actual_email = diff.format_email(1, 1, &updated_commit, None).unwrap();
        let actual_email = actual_email.as_str().unwrap();
        assert!(
            actual_email.starts_with(EXPECTED_EMAIL_START),
            "Unexpected email:\n{}",
            actual_email
        );
        let mut remaining_lines = actual_email[EXPECTED_EMAIL_START.len()..].lines();
        let version_line = remaining_lines.next();
        assert!(
            version_line.unwrap().starts_with("libgit2"),
            "Invalid version line: {:?}",
            version_line
        );
        while let Some(line) = remaining_lines.next() {
            assert_eq!(line.trim(), "")
        }
    }

    #[test]
    fn foreach_diff_line_origin_value() {
        let foo_path = Path::new("foo");
        let (td, repo) = crate::test::repo_init();
        t!(t!(File::create(&td.path().join(foo_path))).write_all(b"bar\n"));
        let mut index = t!(repo.index());
        t!(index.add_path(foo_path));
        let mut opts = DiffOptions::new();
        opts.include_untracked(true);
        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));
        let mut origin_values: Vec<DiffLineType> = Vec::new();
        t!(diff.foreach(
            &mut |_file, _progress| { true },
            None,
            None,
            Some(&mut |_file, _hunk, line| {
                origin_values.push(line.origin_value());
                true
            })
        ));
        assert_eq!(origin_values.len(), 1);
        assert_eq!(origin_values[0], DiffLineType::Addition);
    }

    #[test]
    fn foreach_exits_with_euser() {
        let foo_path = Path::new("foo");
        let bar_path = Path::new("foo");

        let (td, repo) = crate::test::repo_init();
        t!(t!(File::create(&td.path().join(foo_path))).write_all(b"bar\n"));

        let mut index = t!(repo.index());
        t!(index.add_path(foo_path));
        t!(index.add_path(bar_path));

        let mut opts = DiffOptions::new();
        opts.include_untracked(true);
        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));

        let mut calls = 0;
        let result = diff.foreach(
            &mut |_file, _progress| {
                calls += 1;
                false
            },
            None,
            None,
            None,
        );

        assert_eq!(result.unwrap_err().code(), crate::ErrorCode::User);
    }
}
