use libc::size_t;
use std::marker;
use std::ops::Range;
use std::str;

use crate::util::Binding;
use crate::{raw, signature, Error, Oid, Signature};

/// A reference log of a git repository.
pub struct Reflog {
    raw: *mut raw::git_reflog,
}

/// An entry inside the reflog of a repository
pub struct ReflogEntry<'reflog> {
    raw: *const raw::git_reflog_entry,
    _marker: marker::PhantomData<&'reflog Reflog>,
}

/// An iterator over the entries inside of a reflog.
pub struct ReflogIter<'reflog> {
    range: Range<usize>,
    reflog: &'reflog Reflog,
}

impl Reflog {
    /// Add a new entry to the in-memory reflog.
    pub fn append(
        &mut self,
        new_oid: Oid,
        committer: &Signature<'_>,
        msg: Option<&str>,
    ) -> Result<(), Error> {
        let msg = crate::opt_cstr(msg)?;
        unsafe {
            try_call!(raw::git_reflog_append(
                self.raw,
                new_oid.raw(),
                committer.raw(),
                msg
            ));
        }
        Ok(())
    }

    /// Remove an entry from the reflog by its index
    ///
    /// To ensure there's no gap in the log history, set rewrite_previous_entry
    /// param value to `true`. When deleting entry n, member old_oid of entry
    /// n-1 (if any) will be updated with the value of member new_oid of entry
    /// n+1.
    pub fn remove(&mut self, i: usize, rewrite_previous_entry: bool) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_reflog_drop(
                self.raw,
                i as size_t,
                rewrite_previous_entry
            ));
        }
        Ok(())
    }

    /// Lookup an entry by its index
    ///
    /// Requesting the reflog entry with an index of 0 (zero) will return the
    /// most recently created entry.
    pub fn get(&self, i: usize) -> Option<ReflogEntry<'_>> {
        unsafe {
            let ptr = raw::git_reflog_entry_byindex(self.raw, i as size_t);
            Binding::from_raw_opt(ptr)
        }
    }

    /// Get the number of log entries in a reflog
    pub fn len(&self) -> usize {
        unsafe { raw::git_reflog_entrycount(self.raw) as usize }
    }

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

    /// Get an iterator to all entries inside of this reflog
    pub fn iter(&self) -> ReflogIter<'_> {
        ReflogIter {
            range: 0..self.len(),
            reflog: self,
        }
    }

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

impl Binding for Reflog {
    type Raw = *mut raw::git_reflog;

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

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

impl<'reflog> ReflogEntry<'reflog> {
    /// Get the committer of this entry
    pub fn committer(&self) -> Signature<'_> {
        unsafe {
            let ptr = raw::git_reflog_entry_committer(self.raw);
            signature::from_raw_const(self, ptr)
        }
    }

    /// Get the new oid
    pub fn id_new(&self) -> Oid {
        unsafe { Binding::from_raw(raw::git_reflog_entry_id_new(self.raw)) }
    }

    /// Get the old oid
    pub fn id_old(&self) -> Oid {
        unsafe { Binding::from_raw(raw::git_reflog_entry_id_old(self.raw)) }
    }

    /// Get the log message, returning `None` on invalid UTF-8.
    pub fn message(&self) -> Option<&str> {
        self.message_bytes().and_then(|s| str::from_utf8(s).ok())
    }

    /// Get the log message as a byte array.
    pub fn message_bytes(&self) -> Option<&[u8]> {
        unsafe { crate::opt_bytes(self, raw::git_reflog_entry_message(self.raw)) }
    }
}

impl<'reflog> Binding for ReflogEntry<'reflog> {
    type Raw = *const raw::git_reflog_entry;

    unsafe fn from_raw(raw: *const raw::git_reflog_entry) -> ReflogEntry<'reflog> {
        ReflogEntry {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *const raw::git_reflog_entry {
        self.raw
    }
}

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

#[cfg(test)]
mod tests {
    #[test]
    fn smoke() {
        let (_td, repo) = crate::test::repo_init();
        let mut reflog = repo.reflog("HEAD").unwrap();
        assert_eq!(reflog.iter().len(), 1);
        reflog.write().unwrap();

        let entry = reflog.iter().next().unwrap();
        assert!(entry.message().is_some());

        repo.reflog_rename("HEAD", "refs/heads/foo").unwrap();
        repo.reflog_delete("refs/heads/foo").unwrap();
    }
}
