use crate::util::{self, Binding};
use crate::{raw, signature, Oid, Repository, Signature};
use std::marker;
use std::mem;
use std::ops::Range;
use std::path::Path;

/// Opaque structure to hold blame results.
pub struct Blame<'repo> {
    raw: *mut raw::git_blame,
    _marker: marker::PhantomData<&'repo Repository>,
}

/// Structure that represents a blame hunk.
pub struct BlameHunk<'blame> {
    raw: *mut raw::git_blame_hunk,
    _marker: marker::PhantomData<&'blame raw::git_blame>,
}

/// Blame options
pub struct BlameOptions {
    raw: raw::git_blame_options,
}

/// An iterator over the hunks in a blame.
pub struct BlameIter<'blame> {
    range: Range<usize>,
    blame: &'blame Blame<'blame>,
}

impl<'repo> Blame<'repo> {
    /// Gets the number of hunks that exist in the blame structure.
    pub fn len(&self) -> usize {
        unsafe { raw::git_blame_get_hunk_count(self.raw) as usize }
    }

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

    /// Gets the blame hunk at the given index.
    pub fn get_index(&self, index: usize) -> Option<BlameHunk<'_>> {
        unsafe {
            let ptr = raw::git_blame_get_hunk_byindex(self.raw(), index as u32);
            if ptr.is_null() {
                None
            } else {
                Some(BlameHunk::from_raw_const(ptr))
            }
        }
    }

    /// Gets the hunk that relates to the given line number in the newest
    /// commit.
    pub fn get_line(&self, lineno: usize) -> Option<BlameHunk<'_>> {
        unsafe {
            let ptr = raw::git_blame_get_hunk_byline(self.raw(), lineno);
            if ptr.is_null() {
                None
            } else {
                Some(BlameHunk::from_raw_const(ptr))
            }
        }
    }

    /// Returns an iterator over the hunks in this blame.
    pub fn iter(&self) -> BlameIter<'_> {
        BlameIter {
            range: 0..self.len(),
            blame: self,
        }
    }
}

impl<'blame> BlameHunk<'blame> {
    unsafe fn from_raw_const(raw: *const raw::git_blame_hunk) -> BlameHunk<'blame> {
        BlameHunk {
            raw: raw as *mut raw::git_blame_hunk,
            _marker: marker::PhantomData,
        }
    }

    /// Returns OID of the commit where this line was last changed
    pub fn final_commit_id(&self) -> Oid {
        unsafe { Oid::from_raw(&(*self.raw).final_commit_id) }
    }

    /// Returns signature of the commit.
    pub fn final_signature(&self) -> Signature<'_> {
        unsafe { signature::from_raw_const(self, (*self.raw).final_signature) }
    }

    /// Returns line number where this hunk begins.
    ///
    /// Note that the start line is counting from 1.
    pub fn final_start_line(&self) -> usize {
        unsafe { (*self.raw).final_start_line_number }
    }

    /// Returns the OID of the commit where this hunk was found.
    ///
    /// This will usually be the same as `final_commit_id`,
    /// except when `BlameOptions::track_copies_any_commit_copies` has been
    /// turned on
    pub fn orig_commit_id(&self) -> Oid {
        unsafe { Oid::from_raw(&(*self.raw).orig_commit_id) }
    }

    /// Returns signature of the commit.
    pub fn orig_signature(&self) -> Signature<'_> {
        unsafe { signature::from_raw_const(self, (*self.raw).orig_signature) }
    }

    /// Returns line number where this hunk begins.
    ///
    /// Note that the start line is counting from 1.
    pub fn orig_start_line(&self) -> usize {
        unsafe { (*self.raw).orig_start_line_number }
    }

    /// Returns path to the file where this hunk originated.
    ///
    /// Note: `None` could be returned for non-unicode paths on Widnows.
    pub fn path(&self) -> Option<&Path> {
        unsafe {
            if let Some(bytes) = crate::opt_bytes(self, (*self.raw).orig_path) {
                Some(util::bytes2path(bytes))
            } else {
                None
            }
        }
    }

    /// Tests whether this hunk has been tracked to a boundary commit
    /// (the root, or the commit specified in git_blame_options.oldest_commit).
    pub fn is_boundary(&self) -> bool {
        unsafe { (*self.raw).boundary == 1 }
    }

    /// Returns number of lines in this hunk.
    pub fn lines_in_hunk(&self) -> usize {
        unsafe { (*self.raw).lines_in_hunk as usize }
    }
}

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

impl BlameOptions {
    /// Initialize options
    pub fn new() -> BlameOptions {
        unsafe {
            let mut raw: raw::git_blame_options = mem::zeroed();
            assert_eq!(
                raw::git_blame_init_options(&mut raw, raw::GIT_BLAME_OPTIONS_VERSION),
                0
            );

            Binding::from_raw(&raw as *const _ as *mut _)
        }
    }

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

    /// Track lines that have moved within a file.
    pub fn track_copies_same_file(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_TRACK_COPIES_SAME_FILE, opt)
    }

    /// Track lines that have moved across files in the same commit.
    pub fn track_copies_same_commit_moves(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES, opt)
    }

    /// Track lines that have been copied from another file that exists
    /// in the same commit.
    pub fn track_copies_same_commit_copies(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES, opt)
    }

    /// Track lines that have been copied from another file that exists
    /// in any commit.
    pub fn track_copies_any_commit_copies(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES, opt)
    }

    /// Restrict the search of commits to those reachable following only
    /// the first parents.
    pub fn first_parent(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_FIRST_PARENT, opt)
    }

    /// Use mailmap file to map author and committer names and email addresses
    /// to canonical real names and email addresses. The mailmap will be read
    /// from the working directory, or HEAD in a bare repository.
    pub fn use_mailmap(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_USE_MAILMAP, opt)
    }

    /// Ignore whitespace differences.
    pub fn ignore_whitespace(&mut self, opt: bool) -> &mut BlameOptions {
        self.flag(raw::GIT_BLAME_IGNORE_WHITESPACE, opt)
    }

    /// Setter for the id of the newest commit to consider.
    pub fn newest_commit(&mut self, id: Oid) -> &mut BlameOptions {
        unsafe {
            self.raw.newest_commit = *id.raw();
        }
        self
    }

    /// Setter for the id of the oldest commit to consider.
    pub fn oldest_commit(&mut self, id: Oid) -> &mut BlameOptions {
        unsafe {
            self.raw.oldest_commit = *id.raw();
        }
        self
    }

    /// The first line in the file to blame.
    pub fn min_line(&mut self, lineno: usize) -> &mut BlameOptions {
        self.raw.min_line = lineno;
        self
    }

    /// The last line in the file to blame.
    pub fn max_line(&mut self, lineno: usize) -> &mut BlameOptions {
        self.raw.max_line = lineno;
        self
    }
}

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

    unsafe fn from_raw(raw: *mut raw::git_blame) -> Blame<'repo> {
        Blame {
            raw,
            _marker: marker::PhantomData,
        }
    }

    fn raw(&self) -> *mut raw::git_blame {
        self.raw
    }
}

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

impl<'blame> Binding for BlameHunk<'blame> {
    type Raw = *mut raw::git_blame_hunk;

    unsafe fn from_raw(raw: *mut raw::git_blame_hunk) -> BlameHunk<'blame> {
        BlameHunk {
            raw,
            _marker: marker::PhantomData,
        }
    }

    fn raw(&self) -> *mut raw::git_blame_hunk {
        self.raw
    }
}

impl Binding for BlameOptions {
    type Raw = *mut raw::git_blame_options;

    unsafe fn from_raw(opts: *mut raw::git_blame_options) -> BlameOptions {
        BlameOptions { raw: *opts }
    }

    fn raw(&self) -> *mut raw::git_blame_options {
        &self.raw as *const _ as *mut _
    }
}

impl<'blame> Iterator for BlameIter<'blame> {
    type Item = BlameHunk<'blame>;
    fn next(&mut self) -> Option<BlameHunk<'blame>> {
        self.range.next().and_then(|i| self.blame.get_index(i))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.range.size_hint()
    }
}

impl<'blame> DoubleEndedIterator for BlameIter<'blame> {
    fn next_back(&mut self) -> Option<BlameHunk<'blame>> {
        self.range.next_back().and_then(|i| self.blame.get_index(i))
    }
}

impl<'blame> ExactSizeIterator for BlameIter<'blame> {}

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

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

        let root = repo.workdir().unwrap();
        fs::create_dir(&root.join("foo")).unwrap();
        File::create(&root.join("foo/bar")).unwrap();
        index.add_path(Path::new("foo/bar")).unwrap();

        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 blame = repo.blame_file(Path::new("foo/bar"), None).unwrap();

        assert_eq!(blame.len(), 1);
        assert_eq!(blame.iter().count(), 1);

        let hunk = blame.get_index(0).unwrap();
        assert_eq!(hunk.final_commit_id(), commit);
        assert_eq!(hunk.final_signature().name(), sig.name());
        assert_eq!(hunk.final_signature().email(), sig.email());
        assert_eq!(hunk.final_start_line(), 1);
        assert_eq!(hunk.path(), Some(Path::new("foo/bar")));
        assert_eq!(hunk.lines_in_hunk(), 0);
        assert!(!hunk.is_boundary())
    }
}
