//! # libgit2 bindings for Rust
//!
//! This library contains bindings to the [libgit2][1] C library which is used
//! to manage git repositories. The library itself is a work in progress and is
//! likely lacking some bindings here and there, so be warned.
//!
//! [1]: https://libgit2.github.com/
//!
//! The git2-rs library strives to be as close to libgit2 as possible, but also
//! strives to make using libgit2 as safe as possible. All resource management
//! is automatic as well as adding strong types to all interfaces (including
//! `Result`)
//!
//! ## Creating a `Repository`
//!
//! The `Repository` is the source from which almost all other objects in git-rs
//! are spawned. A repository can be created through opening, initializing, or
//! cloning.
//!
//! ### Initializing a new repository
//!
//! The `init` method will create a new repository, assuming one does not
//! already exist.
//!
//! ```no_run
//! # #![allow(unstable)]
//! use git2::Repository;
//!
//! let repo = match Repository::init("/path/to/a/repo") {
//!     Ok(repo) => repo,
//!     Err(e) => panic!("failed to init: {}", e),
//! };
//! ```
//!
//! ### Opening an existing repository
//!
//! ```no_run
//! # #![allow(unstable)]
//! use git2::Repository;
//!
//! let repo = match Repository::open("/path/to/a/repo") {
//!     Ok(repo) => repo,
//!     Err(e) => panic!("failed to open: {}", e),
//! };
//! ```
//!
//! ### Cloning an existing repository
//!
//! ```no_run
//! # #![allow(unstable)]
//! use git2::Repository;
//!
//! let url = "https://github.com/alexcrichton/git2-rs";
//! let repo = match Repository::clone(url, "/path/to/a/repo") {
//!     Ok(repo) => repo,
//!     Err(e) => panic!("failed to clone: {}", e),
//! };
//! ```
//!
//! To clone using SSH, refer to [RepoBuilder](./build/struct.RepoBuilder.html).
//!
//! ## Working with a `Repository`
//!
//! All derivative objects, references, etc are attached to the lifetime of the
//! source `Repository`, to ensure that they do not outlive the repository
//! itself.

#![doc(html_root_url = "https://docs.rs/git2/0.13")]
#![allow(trivial_numeric_casts, trivial_casts)]
#![deny(missing_docs)]
#![warn(rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]

use bitflags::bitflags;
use libgit2_sys as raw;

use std::ffi::{CStr, CString};
use std::fmt;
use std::str;
use std::sync::Once;

pub use crate::apply::{ApplyLocation, ApplyOptions};
pub use crate::attr::AttrValue;
pub use crate::blame::{Blame, BlameHunk, BlameIter, BlameOptions};
pub use crate::blob::{Blob, BlobWriter};
pub use crate::branch::{Branch, Branches};
pub use crate::buf::Buf;
pub use crate::cherrypick::CherrypickOptions;
pub use crate::commit::{Commit, Parents};
pub use crate::config::{Config, ConfigEntries, ConfigEntry};
pub use crate::cred::{Cred, CredentialHelper};
pub use crate::describe::{Describe, DescribeFormatOptions, DescribeOptions};
pub use crate::diff::{Deltas, Diff, DiffDelta, DiffFile, DiffOptions};
pub use crate::diff::{DiffBinary, DiffBinaryFile, DiffBinaryKind};
pub use crate::diff::{DiffFindOptions, DiffHunk, DiffLine, DiffLineType, DiffStats};
pub use crate::error::Error;
pub use crate::index::{
    Index, IndexConflict, IndexConflicts, IndexEntries, IndexEntry, IndexMatchedPath,
};
pub use crate::indexer::{IndexerProgress, Progress};
pub use crate::mailmap::Mailmap;
pub use crate::mempack::Mempack;
pub use crate::merge::{AnnotatedCommit, MergeOptions};
pub use crate::message::{
    message_prettify, message_trailers_bytes, message_trailers_strs, MessageTrailersBytes,
    MessageTrailersBytesIterator, MessageTrailersStrs, MessageTrailersStrsIterator,
    DEFAULT_COMMENT_CHAR,
};
pub use crate::note::{Note, Notes};
pub use crate::object::Object;
pub use crate::odb::{Odb, OdbObject, OdbPackwriter, OdbReader, OdbWriter};
pub use crate::oid::Oid;
pub use crate::packbuilder::{PackBuilder, PackBuilderStage};
pub use crate::patch::Patch;
pub use crate::pathspec::{Pathspec, PathspecFailedEntries, PathspecMatchList};
pub use crate::pathspec::{PathspecDiffEntries, PathspecEntries};
pub use crate::proxy_options::ProxyOptions;
pub use crate::rebase::{Rebase, RebaseOperation, RebaseOperationType, RebaseOptions};
pub use crate::reference::{Reference, ReferenceNames, References};
pub use crate::reflog::{Reflog, ReflogEntry, ReflogIter};
pub use crate::refspec::Refspec;
pub use crate::remote::{
    FetchOptions, PushOptions, Refspecs, Remote, RemoteConnection, RemoteHead,
};
pub use crate::remote_callbacks::{Credentials, RemoteCallbacks};
pub use crate::remote_callbacks::{TransportMessage, UpdateTips};
pub use crate::repo::{Repository, RepositoryInitOptions};
pub use crate::revert::RevertOptions;
pub use crate::revspec::Revspec;
pub use crate::revwalk::Revwalk;
pub use crate::signature::Signature;
pub use crate::stash::{StashApplyOptions, StashApplyProgressCb, StashCb};
pub use crate::status::{StatusEntry, StatusIter, StatusOptions, StatusShow, Statuses};
pub use crate::submodule::{Submodule, SubmoduleUpdateOptions};
pub use crate::tag::Tag;
pub use crate::time::{IndexTime, Time};
pub use crate::tracing::{trace_set, TraceLevel};
pub use crate::transaction::Transaction;
pub use crate::tree::{Tree, TreeEntry, TreeIter, TreeWalkMode, TreeWalkResult};
pub use crate::treebuilder::TreeBuilder;
pub use crate::util::IntoCString;
pub use crate::version::Version;
pub use crate::worktree::{Worktree, WorktreeAddOptions, WorktreeLockStatus, WorktreePruneOptions};

// Create a convinience method on bitflag struct which checks the given flag
macro_rules! is_bit_set {
    ($name:ident, $flag:expr) => {
        #[allow(missing_docs)]
        pub fn $name(&self) -> bool {
            self.intersects($flag)
        }
    };
}

/// An enumeration of possible errors that can happen when working with a git
/// repository.
// Note: We omit a few native error codes, as they are unlikely to be propagated
// to the library user. Currently:
//
// * GIT_EPASSTHROUGH
// * GIT_ITEROVER
// * GIT_RETRY
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum ErrorCode {
    /// Generic error
    GenericError,
    /// Requested object could not be found
    NotFound,
    /// Object exists preventing operation
    Exists,
    /// More than one object matches
    Ambiguous,
    /// Output buffer too short to hold data
    BufSize,
    /// User-generated error
    User,
    /// Operation not allowed on bare repository
    BareRepo,
    /// HEAD refers to branch with no commits
    UnbornBranch,
    /// Merge in progress prevented operation
    Unmerged,
    /// Reference was not fast-forwardable
    NotFastForward,
    /// Name/ref spec was not in a valid format
    InvalidSpec,
    /// Checkout conflicts prevented operation
    Conflict,
    /// Lock file prevented operation
    Locked,
    /// Reference value does not match expected
    Modified,
    /// Authentication error
    Auth,
    /// Server certificate is invalid
    Certificate,
    /// Patch/merge has already been applied
    Applied,
    /// The requested peel operation is not possible
    Peel,
    /// Unexpected EOF
    Eof,
    /// Invalid operation or input
    Invalid,
    /// Uncommitted changes in index prevented operation
    Uncommitted,
    /// Operation was not valid for a directory
    Directory,
    /// A merge conflict exists and cannot continue
    MergeConflict,
    /// Hashsum mismatch in object
    HashsumMismatch,
    /// Unsaved changes in the index would be overwritten
    IndexDirty,
    /// Patch application failed
    ApplyFail,
}

/// An enumeration of possible categories of things that can have
/// errors when working with a git repository.
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum ErrorClass {
    /// Uncategorized
    None,
    /// Out of memory or insufficient allocated space
    NoMemory,
    /// Syscall or standard system library error
    Os,
    /// Invalid input
    Invalid,
    /// Error resolving or manipulating a reference
    Reference,
    /// ZLib failure
    Zlib,
    /// Bad repository state
    Repository,
    /// Bad configuration
    Config,
    /// Regex failure
    Regex,
    /// Bad object
    Odb,
    /// Invalid index data
    Index,
    /// Error creating or obtaining an object
    Object,
    /// Network error
    Net,
    /// Error manpulating a tag
    Tag,
    /// Invalid value in tree
    Tree,
    /// Hashing or packing error
    Indexer,
    /// Error from SSL
    Ssl,
    /// Error involing submodules
    Submodule,
    /// Threading error
    Thread,
    /// Error manipulating a stash
    Stash,
    /// Checkout failure
    Checkout,
    /// Invalid FETCH_HEAD
    FetchHead,
    /// Merge failure
    Merge,
    /// SSH failure
    Ssh,
    /// Error manipulating filters
    Filter,
    /// Error reverting commit
    Revert,
    /// Error from a user callback
    Callback,
    /// Error cherry-picking commit
    CherryPick,
    /// Can't describe object
    Describe,
    /// Error during rebase
    Rebase,
    /// Filesystem-related error
    Filesystem,
    /// Invalid patch data
    Patch,
    /// Error involving worktrees
    Worktree,
    /// Hash library error or SHA-1 collision
    Sha1,
    /// HTTP error
    Http,
}

/// A listing of the possible states that a repository can be in.
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
#[allow(missing_docs)]
pub enum RepositoryState {
    Clean,
    Merge,
    Revert,
    RevertSequence,
    CherryPick,
    CherryPickSequence,
    Bisect,
    Rebase,
    RebaseInteractive,
    RebaseMerge,
    ApplyMailbox,
    ApplyMailboxOrRebase,
}

/// An enumeration of the possible directions for a remote.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Direction {
    /// Data will be fetched (read) from this remote.
    Fetch,
    /// Data will be pushed (written) to this remote.
    Push,
}

/// An enumeration of the operations that can be performed for the `reset`
/// method on a `Repository`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ResetType {
    /// Move the head to the given commit.
    Soft,
    /// Soft plus reset the index to the commit.
    Mixed,
    /// Mixed plus changes in the working tree are discarded.
    Hard,
}

/// An enumeration all possible kinds objects may have.
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum ObjectType {
    /// Any kind of git object
    Any,
    /// An object which corresponds to a git commit
    Commit,
    /// An object which corresponds to a git tree
    Tree,
    /// An object which corresponds to a git blob
    Blob,
    /// An object which corresponds to a git tag
    Tag,
}

/// An enumeration of all possile kinds of references.
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum ReferenceType {
    /// A reference which points at an object id.
    Direct,

    /// A reference which points at another reference.
    Symbolic,
}

/// An enumeration for the possible types of branches
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum BranchType {
    /// A local branch not on a remote.
    Local,
    /// A branch for a remote.
    Remote,
}

/// An enumeration of the possible priority levels of a config file.
///
/// The levels corresponding to the escalation logic (higher to lower) when
/// searching for config entries.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ConfigLevel {
    /// System-wide on Windows, for compatibility with portable git
    ProgramData = 1,
    /// System-wide configuration file, e.g. /etc/gitconfig
    System,
    /// XDG-compatible configuration file, e.g. ~/.config/git/config
    XDG,
    /// User-specific configuration, e.g. ~/.gitconfig
    Global,
    /// Repository specific config, e.g. $PWD/.git/config
    Local,
    /// Application specific configuration file
    App,
    /// Highest level available
    Highest = -1,
}

/// Merge file favor options for `MergeOptions` instruct the file-level
/// merging functionality how to deal with conflicting regions of the files.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum FileFavor {
    /// When a region of a file is changed in both branches, a conflict will be
    /// recorded in the index so that git_checkout can produce a merge file with
    /// conflict markers in the working directory. This is the default.
    Normal,
    /// When a region of a file is changed in both branches, the file created
    /// in the index will contain the "ours" side of any conflicting region.
    /// The index will not record a conflict.
    Ours,
    /// When a region of a file is changed in both branches, the file created
    /// in the index will contain the "theirs" side of any conflicting region.
    /// The index will not record a conflict.
    Theirs,
    /// When a region of a file is changed in both branches, the file created
    /// in the index will contain each unique line from each side, which has
    /// the result of combining both files. The index will not record a conflict.
    Union,
}

bitflags! {
    /// Orderings that may be specified for Revwalk iteration.
    pub struct Sort: u32 {
        /// Sort the repository contents in no particular ordering.
        ///
        /// This sorting is arbitrary, implementation-specific, and subject to
        /// change at any time. This is the default sorting for new walkers.
        const NONE = raw::GIT_SORT_NONE as u32;

        /// Sort the repository contents in topological order (children before
        /// parents).
        ///
        /// This sorting mode can be combined with time sorting.
        const TOPOLOGICAL = raw::GIT_SORT_TOPOLOGICAL as u32;

        /// Sort the repository contents by commit time.
        ///
        /// This sorting mode can be combined with topological sorting.
        const TIME = raw::GIT_SORT_TIME as u32;

        /// Iterate through the repository contents in reverse order.
        ///
        /// This sorting mode can be combined with any others.
        const REVERSE = raw::GIT_SORT_REVERSE as u32;
    }
}

impl Sort {
    is_bit_set!(is_none, Sort::NONE);
    is_bit_set!(is_topological, Sort::TOPOLOGICAL);
    is_bit_set!(is_time, Sort::TIME);
    is_bit_set!(is_reverse, Sort::REVERSE);
}

bitflags! {
    /// Types of credentials that can be requested by a credential callback.
    pub struct CredentialType: u32 {
        #[allow(missing_docs)]
        const USER_PASS_PLAINTEXT = raw::GIT_CREDTYPE_USERPASS_PLAINTEXT as u32;
        #[allow(missing_docs)]
        const SSH_KEY = raw::GIT_CREDTYPE_SSH_KEY as u32;
        #[allow(missing_docs)]
        const SSH_MEMORY = raw::GIT_CREDTYPE_SSH_MEMORY as u32;
        #[allow(missing_docs)]
        const SSH_CUSTOM = raw::GIT_CREDTYPE_SSH_CUSTOM as u32;
        #[allow(missing_docs)]
        const DEFAULT = raw::GIT_CREDTYPE_DEFAULT as u32;
        #[allow(missing_docs)]
        const SSH_INTERACTIVE = raw::GIT_CREDTYPE_SSH_INTERACTIVE as u32;
        #[allow(missing_docs)]
        const USERNAME = raw::GIT_CREDTYPE_USERNAME as u32;
    }
}

impl CredentialType {
    is_bit_set!(is_user_pass_plaintext, CredentialType::USER_PASS_PLAINTEXT);
    is_bit_set!(is_ssh_key, CredentialType::SSH_KEY);
    is_bit_set!(is_ssh_memory, CredentialType::SSH_MEMORY);
    is_bit_set!(is_ssh_custom, CredentialType::SSH_CUSTOM);
    is_bit_set!(is_default, CredentialType::DEFAULT);
    is_bit_set!(is_ssh_interactive, CredentialType::SSH_INTERACTIVE);
    is_bit_set!(is_username, CredentialType::USERNAME);
}

impl Default for CredentialType {
    fn default() -> Self {
        CredentialType::DEFAULT
    }
}

bitflags! {
    /// Flags for the `flags` field of an IndexEntry.
    pub struct IndexEntryFlag: u16 {
        /// Set when the `extended_flags` field is valid.
        const EXTENDED = raw::GIT_INDEX_ENTRY_EXTENDED as u16;
        /// "Assume valid" flag
        const VALID = raw::GIT_INDEX_ENTRY_VALID as u16;
    }
}

impl IndexEntryFlag {
    is_bit_set!(is_extended, IndexEntryFlag::EXTENDED);
    is_bit_set!(is_valid, IndexEntryFlag::VALID);
}

bitflags! {
    /// Flags for the `extended_flags` field of an IndexEntry.
    pub struct IndexEntryExtendedFlag: u16 {
        /// An "intent to add" entry from "git add -N"
        const INTENT_TO_ADD = raw::GIT_INDEX_ENTRY_INTENT_TO_ADD as u16;
        /// Skip the associated worktree file, for sparse checkouts
        const SKIP_WORKTREE = raw::GIT_INDEX_ENTRY_SKIP_WORKTREE as u16;

        #[allow(missing_docs)]
        const UPTODATE = raw::GIT_INDEX_ENTRY_UPTODATE as u16;
    }
}

impl IndexEntryExtendedFlag {
    is_bit_set!(is_intent_to_add, IndexEntryExtendedFlag::INTENT_TO_ADD);
    is_bit_set!(is_skip_worktree, IndexEntryExtendedFlag::SKIP_WORKTREE);
    is_bit_set!(is_up_to_date, IndexEntryExtendedFlag::UPTODATE);
}

bitflags! {
    /// Flags for APIs that add files matching pathspec
    pub struct IndexAddOption: u32 {
        #[allow(missing_docs)]
        const DEFAULT = raw::GIT_INDEX_ADD_DEFAULT as u32;
        #[allow(missing_docs)]
        const FORCE = raw::GIT_INDEX_ADD_FORCE as u32;
        #[allow(missing_docs)]
        const DISABLE_PATHSPEC_MATCH =
                raw::GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH as u32;
        #[allow(missing_docs)]
        const CHECK_PATHSPEC = raw::GIT_INDEX_ADD_CHECK_PATHSPEC as u32;
    }
}

impl IndexAddOption {
    is_bit_set!(is_default, IndexAddOption::DEFAULT);
    is_bit_set!(is_force, IndexAddOption::FORCE);
    is_bit_set!(
        is_disable_pathspec_match,
        IndexAddOption::DISABLE_PATHSPEC_MATCH
    );
    is_bit_set!(is_check_pathspec, IndexAddOption::CHECK_PATHSPEC);
}

impl Default for IndexAddOption {
    fn default() -> Self {
        IndexAddOption::DEFAULT
    }
}

bitflags! {
    /// Flags for `Repository::open_ext`
    pub struct RepositoryOpenFlags: u32 {
        /// Only open the specified path; don't walk upward searching.
        const NO_SEARCH = raw::GIT_REPOSITORY_OPEN_NO_SEARCH as u32;
        /// Search across filesystem boundaries.
        const CROSS_FS = raw::GIT_REPOSITORY_OPEN_CROSS_FS as u32;
        /// Force opening as bare repository, and defer loading its config.
        const BARE = raw::GIT_REPOSITORY_OPEN_BARE as u32;
        /// Don't try appending `/.git` to the specified repository path.
        const NO_DOTGIT = raw::GIT_REPOSITORY_OPEN_NO_DOTGIT as u32;
        /// Respect environment variables like `$GIT_DIR`.
        const FROM_ENV = raw::GIT_REPOSITORY_OPEN_FROM_ENV as u32;
    }
}

impl RepositoryOpenFlags {
    is_bit_set!(is_no_search, RepositoryOpenFlags::NO_SEARCH);
    is_bit_set!(is_cross_fs, RepositoryOpenFlags::CROSS_FS);
    is_bit_set!(is_bare, RepositoryOpenFlags::BARE);
    is_bit_set!(is_no_dotgit, RepositoryOpenFlags::NO_DOTGIT);
    is_bit_set!(is_from_env, RepositoryOpenFlags::FROM_ENV);
}

bitflags! {
    /// Flags for the return value of `Repository::revparse`
    pub struct RevparseMode: u32 {
        /// The spec targeted a single object
        const SINGLE = raw::GIT_REVPARSE_SINGLE as u32;
        /// The spec targeted a range of commits
        const RANGE = raw::GIT_REVPARSE_RANGE as u32;
        /// The spec used the `...` operator, which invokes special semantics.
        const MERGE_BASE = raw::GIT_REVPARSE_MERGE_BASE as u32;
    }
}

impl RevparseMode {
    is_bit_set!(is_no_single, RevparseMode::SINGLE);
    is_bit_set!(is_range, RevparseMode::RANGE);
    is_bit_set!(is_merge_base, RevparseMode::MERGE_BASE);
}

bitflags! {
    /// The results of `merge_analysis` indicating the merge opportunities.
    pub struct MergeAnalysis: u32 {
        /// No merge is possible.
        const ANALYSIS_NONE = raw::GIT_MERGE_ANALYSIS_NONE as u32;
        /// A "normal" merge; both HEAD and the given merge input have diverged
        /// from their common ancestor. The divergent commits must be merged.
        const ANALYSIS_NORMAL = raw::GIT_MERGE_ANALYSIS_NORMAL as u32;
        /// All given merge inputs are reachable from HEAD, meaning the
        /// repository is up-to-date and no merge needs to be performed.
        const ANALYSIS_UP_TO_DATE = raw::GIT_MERGE_ANALYSIS_UP_TO_DATE as u32;
        /// The given merge input is a fast-forward from HEAD and no merge
        /// needs to be performed.  Instead, the client can check out the
        /// given merge input.
        const ANALYSIS_FASTFORWARD = raw::GIT_MERGE_ANALYSIS_FASTFORWARD as u32;
        /// The HEAD of the current repository is "unborn" and does not point to
        /// a valid commit.  No merge can be performed, but the caller may wish
        /// to simply set HEAD to the target commit(s).
        const ANALYSIS_UNBORN = raw::GIT_MERGE_ANALYSIS_UNBORN as u32;
    }
}

impl MergeAnalysis {
    is_bit_set!(is_none, MergeAnalysis::ANALYSIS_NONE);
    is_bit_set!(is_normal, MergeAnalysis::ANALYSIS_NORMAL);
    is_bit_set!(is_up_to_date, MergeAnalysis::ANALYSIS_UP_TO_DATE);
    is_bit_set!(is_fast_forward, MergeAnalysis::ANALYSIS_FASTFORWARD);
    is_bit_set!(is_unborn, MergeAnalysis::ANALYSIS_UNBORN);
}

bitflags! {
    /// The user's stated preference for merges.
    pub struct MergePreference: u32 {
        /// No configuration was found that suggests a preferred behavior for
        /// merge.
        const NONE = raw::GIT_MERGE_PREFERENCE_NONE as u32;
        /// There is a `merge.ff=false` configuration setting, suggesting that
        /// the user does not want to allow a fast-forward merge.
        const NO_FAST_FORWARD = raw::GIT_MERGE_PREFERENCE_NO_FASTFORWARD as u32;
        /// There is a `merge.ff=only` configuration setting, suggesting that
        /// the user only wants fast-forward merges.
        const FASTFORWARD_ONLY = raw::GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY as u32;
    }
}

impl MergePreference {
    is_bit_set!(is_none, MergePreference::NONE);
    is_bit_set!(is_no_fast_forward, MergePreference::NO_FAST_FORWARD);
    is_bit_set!(is_fastforward_only, MergePreference::FASTFORWARD_ONLY);
}

#[cfg(test)]
#[macro_use]
mod test;
#[macro_use]
mod panic;
mod attr;
mod call;
mod util;

pub mod build;
pub mod cert;
pub mod oid_array;
pub mod opts;
pub mod string_array;
pub mod transport;

mod apply;
mod blame;
mod blob;
mod branch;
mod buf;
mod cherrypick;
mod commit;
mod config;
mod cred;
mod describe;
mod diff;
mod error;
mod index;
mod indexer;
mod mailmap;
mod mempack;
mod merge;
mod message;
mod note;
mod object;
mod odb;
mod oid;
mod packbuilder;
mod patch;
mod pathspec;
mod proxy_options;
mod rebase;
mod reference;
mod reflog;
mod refspec;
mod remote;
mod remote_callbacks;
mod repo;
mod revert;
mod revspec;
mod revwalk;
mod signature;
mod stash;
mod status;
mod submodule;
mod tag;
mod tagforeach;
mod time;
mod tracing;
mod transaction;
mod tree;
mod treebuilder;
mod version;
mod worktree;

fn init() {
    static INIT: Once = Once::new();

    INIT.call_once(|| {
        openssl_env_init();
    });

    raw::init();
}

#[cfg(all(
    unix,
    not(target_os = "macos"),
    not(target_os = "ios"),
    feature = "https"
))]
fn openssl_env_init() {
    // Currently, libgit2 leverages OpenSSL for SSL support when cloning
    // repositories over HTTPS. This means that we're picking up an OpenSSL
    // dependency on non-Windows platforms (where it has its own HTTPS
    // subsystem). As a result, we need to link to OpenSSL.
    //
    // Now actually *linking* to OpenSSL isn't so hard. We just need to make
    // sure to use pkg-config to discover any relevant system dependencies for
    // differences between distributions like CentOS and Ubuntu. The actual
    // trickiness comes about when we start *distributing* the resulting
    // binaries. Currently Cargo is distributed in binary form as nightlies,
    // which means we're distributing a binary with OpenSSL linked in.
    //
    // For historical reasons, the Linux nightly builder is running a CentOS
    // distribution in order to have as much ABI compatibility with other
    // distributions as possible. Sadly, however, this compatibility does not
    // extend to OpenSSL. Currently OpenSSL has two major versions, 0.9 and 1.0,
    // which are incompatible (many ABI differences). The CentOS builder we
    // build on has version 1.0, as do most distributions today. Some still have
    // 0.9, however. This means that if we are to distribute the binaries built
    // by the CentOS machine, we would only be compatible with OpenSSL 1.0 and
    // we would fail to run (a dynamic linker error at runtime) on systems with
    // only 9.8 installed (hopefully).
    //
    // But wait, the plot thickens! Apparently CentOS has dubbed their OpenSSL
    // library as `libssl.so.10`, notably the `10` is included at the end. On
    // the other hand Ubuntu, for example, only distributes `libssl.so`. This
    // means that the binaries created at CentOS are hard-wired to probe for a
    // file called `libssl.so.10` at runtime (using the LD_LIBRARY_PATH), which
    // will not be found on ubuntu. The conclusion of this is that binaries
    // built on CentOS cannot be distributed to Ubuntu and run successfully.
    //
    // There are a number of sneaky things we could do, including, but not
    // limited to:
    //
    // 1. Create a shim program which runs "just before" cargo runs. The
    //    responsibility of this shim program would be to locate `libssl.so`,
    //    whatever it's called, on the current system, make sure there's a
    //    symlink *somewhere* called `libssl.so.10`, and then set up
    //    LD_LIBRARY_PATH and run the actual cargo.
    //
    //    This approach definitely seems unconventional, and is borderline
    //    overkill for this problem. It's also dubious if we can find a
    //    libssl.so reliably on the target system.
    //
    // 2. Somehow re-work the CentOS installation so that the linked-against
    //    library is called libssl.so instead of libssl.so.10
    //
    //    The problem with this approach is that systems with 0.9 installed will
    //    start to silently fail, due to also having libraries called libssl.so
    //    (probably symlinked under a more appropriate version).
    //
    // 3. Compile Cargo against both OpenSSL 1.0 *and* OpenSSL 0.9, and
    //    distribute both. Also make sure that the linked-against name of the
    //    library is `libssl.so`. At runtime we determine which version is
    //    installed, and we then the appropriate binary.
    //
    //    This approach clearly has drawbacks in terms of infrastructure and
    //    feasibility.
    //
    // 4. Build a nightly of Cargo for each distribution we'd like to support.
    //    You would then pick the appropriate Cargo nightly to install locally.
    //
    // So, with all this in mind, the decision was made to *statically* link
    // OpenSSL. This solves any problem of relying on a downstream OpenSSL
    // version being available. This does, however, open a can of worms related
    // to security issues. It's generally a good idea to dynamically link
    // OpenSSL as you'll get security updates over time without having to do
    // anything (the system administrator will update the local openssl
    // package). By statically linking, we're forfeiting this feature.
    //
    // The conclusion was made it is likely appropriate for the Cargo nightlies
    // to statically link OpenSSL, but highly encourage distributions and
    // packagers of Cargo to dynamically link OpenSSL. Packagers are targeting
    // one system and are distributing to only that system, so none of the
    // problems mentioned above would arise.
    //
    // In order to support this, a new package was made: openssl-static-sys.
    // This package currently performs a fairly simple task:
    //
    // 1. Run pkg-config to discover where openssl is installed.
    // 2. If openssl is installed in a nonstandard location, *and* static copies
    //    of the libraries are available, copy them to $OUT_DIR.
    //
    // This library will bring in libssl.a and libcrypto.a into the local build,
    // allowing them to be picked up by this crate. This allows us to configure
    // our own buildbots to have pkg-config point to these local pre-built
    // copies of a static OpenSSL (with very few dependencies) while allowing
    // most other builds of Cargo to naturally dynamically link OpenSSL.
    //
    // So in summary, if you're with me so far, we've statically linked OpenSSL
    // to the Cargo binary (or any binary, for that matter) and we're ready to
    // distribute it to *all* linux distributions. Remember that our original
    // intent for openssl was for HTTPS support, which implies that we need some
    // for of CA certificate store to validate certificates. This is normally
    // installed in a standard system location.
    //
    // Unfortunately, as one might imagine, OpenSSL is configured for where this
    // standard location is at *build time*, but it often varies widely
    // per-system. Consequently, it was discovered that OpenSSL will respect the
    // SSL_CERT_FILE and SSL_CERT_DIR environment variables in order to assist
    // in discovering the location of this file (hurray!).
    //
    // So, finally getting to the point, this function solely exists to support
    // our static builds of OpenSSL by probing for the "standard system
    // location" of certificates and setting relevant environment variable to
    // point to them.
    //
    // Ah, and as a final note, this is only a problem on Linux, not on OS X. On
    // OS X the OpenSSL binaries are stable enough that we can just rely on
    // dynamic linkage (plus they have some weird modifications to OpenSSL which
    // means we wouldn't want to link statically).
    openssl_probe::init_ssl_cert_env_vars();
}

#[cfg(any(
    windows,
    target_os = "macos",
    target_os = "ios",
    not(feature = "https")
))]
fn openssl_env_init() {}

unsafe fn opt_bytes<'a, T>(_anchor: &'a T, c: *const libc::c_char) -> Option<&'a [u8]> {
    if c.is_null() {
        None
    } else {
        Some(CStr::from_ptr(c).to_bytes())
    }
}

fn opt_cstr<T: IntoCString>(o: Option<T>) -> Result<Option<CString>, Error> {
    match o {
        Some(s) => s.into_c_string().map(Some),
        None => Ok(None),
    }
}

impl ObjectType {
    /// Convert an object type to its string representation.
    pub fn str(&self) -> &'static str {
        unsafe {
            let ptr = call!(raw::git_object_type2string(*self)) as *const _;
            let data = CStr::from_ptr(ptr).to_bytes();
            str::from_utf8(data).unwrap()
        }
    }

    /// Determine if the given git_object_t is a valid loose object type.
    pub fn is_loose(&self) -> bool {
        unsafe { call!(raw::git_object_typeisloose(*self)) == 1 }
    }

    /// Convert a raw git_object_t to an ObjectType
    pub fn from_raw(raw: raw::git_object_t) -> Option<ObjectType> {
        match raw {
            raw::GIT_OBJECT_ANY => Some(ObjectType::Any),
            raw::GIT_OBJECT_COMMIT => Some(ObjectType::Commit),
            raw::GIT_OBJECT_TREE => Some(ObjectType::Tree),
            raw::GIT_OBJECT_BLOB => Some(ObjectType::Blob),
            raw::GIT_OBJECT_TAG => Some(ObjectType::Tag),
            _ => None,
        }
    }

    /// Convert this kind into its raw representation
    pub fn raw(&self) -> raw::git_object_t {
        call::convert(self)
    }

    /// Convert a string object type representation to its object type.
    pub fn from_str(s: &str) -> Option<ObjectType> {
        let raw = unsafe { call!(raw::git_object_string2type(CString::new(s).unwrap())) };
        ObjectType::from_raw(raw)
    }
}

impl fmt::Display for ObjectType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.str().fmt(f)
    }
}

impl ReferenceType {
    /// Convert an object type to its string representation.
    pub fn str(&self) -> &'static str {
        match self {
            ReferenceType::Direct => "direct",
            ReferenceType::Symbolic => "symbolic",
        }
    }

    /// Convert a raw git_reference_t to a ReferenceType.
    pub fn from_raw(raw: raw::git_reference_t) -> Option<ReferenceType> {
        match raw {
            raw::GIT_REFERENCE_DIRECT => Some(ReferenceType::Direct),
            raw::GIT_REFERENCE_SYMBOLIC => Some(ReferenceType::Symbolic),
            _ => None,
        }
    }
}

impl fmt::Display for ReferenceType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.str().fmt(f)
    }
}

impl ConfigLevel {
    /// Converts a raw configuration level to a ConfigLevel
    pub fn from_raw(raw: raw::git_config_level_t) -> ConfigLevel {
        match raw {
            raw::GIT_CONFIG_LEVEL_PROGRAMDATA => ConfigLevel::ProgramData,
            raw::GIT_CONFIG_LEVEL_SYSTEM => ConfigLevel::System,
            raw::GIT_CONFIG_LEVEL_XDG => ConfigLevel::XDG,
            raw::GIT_CONFIG_LEVEL_GLOBAL => ConfigLevel::Global,
            raw::GIT_CONFIG_LEVEL_LOCAL => ConfigLevel::Local,
            raw::GIT_CONFIG_LEVEL_APP => ConfigLevel::App,
            raw::GIT_CONFIG_HIGHEST_LEVEL => ConfigLevel::Highest,
            n => panic!("unknown config level: {}", n),
        }
    }
}

impl SubmoduleIgnore {
    /// Converts a [`raw::git_submodule_ignore_t`] to a [`SubmoduleIgnore`]
    pub fn from_raw(raw: raw::git_submodule_ignore_t) -> Self {
        match raw {
            raw::GIT_SUBMODULE_IGNORE_UNSPECIFIED => SubmoduleIgnore::Unspecified,
            raw::GIT_SUBMODULE_IGNORE_NONE => SubmoduleIgnore::None,
            raw::GIT_SUBMODULE_IGNORE_UNTRACKED => SubmoduleIgnore::Untracked,
            raw::GIT_SUBMODULE_IGNORE_DIRTY => SubmoduleIgnore::Dirty,
            raw::GIT_SUBMODULE_IGNORE_ALL => SubmoduleIgnore::All,
            n => panic!("unknown submodule ignore rule: {}", n),
        }
    }
}

impl SubmoduleUpdate {
    /// Converts a [`raw::git_submodule_update_t`] to a [`SubmoduleUpdate`]
    pub fn from_raw(raw: raw::git_submodule_update_t) -> Self {
        match raw {
            raw::GIT_SUBMODULE_UPDATE_CHECKOUT => SubmoduleUpdate::Checkout,
            raw::GIT_SUBMODULE_UPDATE_REBASE => SubmoduleUpdate::Rebase,
            raw::GIT_SUBMODULE_UPDATE_MERGE => SubmoduleUpdate::Merge,
            raw::GIT_SUBMODULE_UPDATE_NONE => SubmoduleUpdate::None,
            raw::GIT_SUBMODULE_UPDATE_DEFAULT => SubmoduleUpdate::Default,
            n => panic!("unknown submodule update strategy: {}", n),
        }
    }
}

bitflags! {
    /// Status flags for a single file
    ///
    /// A combination of these values will be returned to indicate the status of
    /// a file.  Status compares the working directory, the index, and the
    /// current HEAD of the repository.  The `STATUS_INDEX_*` set of flags
    /// represents the status of file in the index relative to the HEAD, and the
    /// `STATUS_WT_*` set of flags represent the status of the file in the
    /// working directory relative to the index.
    pub struct Status: u32 {
        #[allow(missing_docs)]
        const CURRENT = raw::GIT_STATUS_CURRENT as u32;

        #[allow(missing_docs)]
        const INDEX_NEW = raw::GIT_STATUS_INDEX_NEW as u32;
        #[allow(missing_docs)]
        const INDEX_MODIFIED = raw::GIT_STATUS_INDEX_MODIFIED as u32;
        #[allow(missing_docs)]
        const INDEX_DELETED = raw::GIT_STATUS_INDEX_DELETED as u32;
        #[allow(missing_docs)]
        const INDEX_RENAMED = raw::GIT_STATUS_INDEX_RENAMED as u32;
        #[allow(missing_docs)]
        const INDEX_TYPECHANGE = raw::GIT_STATUS_INDEX_TYPECHANGE as u32;

        #[allow(missing_docs)]
        const WT_NEW = raw::GIT_STATUS_WT_NEW as u32;
        #[allow(missing_docs)]
        const WT_MODIFIED = raw::GIT_STATUS_WT_MODIFIED as u32;
        #[allow(missing_docs)]
        const WT_DELETED = raw::GIT_STATUS_WT_DELETED as u32;
        #[allow(missing_docs)]
        const WT_TYPECHANGE = raw::GIT_STATUS_WT_TYPECHANGE as u32;
        #[allow(missing_docs)]
        const WT_RENAMED = raw::GIT_STATUS_WT_RENAMED as u32;

        #[allow(missing_docs)]
        const IGNORED = raw::GIT_STATUS_IGNORED as u32;
        #[allow(missing_docs)]
        const CONFLICTED = raw::GIT_STATUS_CONFLICTED as u32;
    }
}

impl Status {
    is_bit_set!(is_index_new, Status::INDEX_NEW);
    is_bit_set!(is_index_modified, Status::INDEX_MODIFIED);
    is_bit_set!(is_index_deleted, Status::INDEX_DELETED);
    is_bit_set!(is_index_renamed, Status::INDEX_RENAMED);
    is_bit_set!(is_index_typechange, Status::INDEX_TYPECHANGE);
    is_bit_set!(is_wt_new, Status::WT_NEW);
    is_bit_set!(is_wt_modified, Status::WT_MODIFIED);
    is_bit_set!(is_wt_deleted, Status::WT_DELETED);
    is_bit_set!(is_wt_typechange, Status::WT_TYPECHANGE);
    is_bit_set!(is_wt_renamed, Status::WT_RENAMED);
    is_bit_set!(is_ignored, Status::IGNORED);
    is_bit_set!(is_conflicted, Status::CONFLICTED);
}

bitflags! {
    /// Mode options for RepositoryInitOptions
    pub struct RepositoryInitMode: u32 {
        /// Use permissions configured by umask - the default
        const SHARED_UMASK = raw::GIT_REPOSITORY_INIT_SHARED_UMASK as u32;
        /// Use `--shared=group` behavior, chmod'ing the new repo to be
        /// group writable and \"g+sx\" for sticky group assignment
        const SHARED_GROUP = raw::GIT_REPOSITORY_INIT_SHARED_GROUP as u32;
        /// Use `--shared=all` behavior, adding world readability.
        const SHARED_ALL = raw::GIT_REPOSITORY_INIT_SHARED_ALL as u32;
    }
}

impl RepositoryInitMode {
    is_bit_set!(is_shared_umask, RepositoryInitMode::SHARED_UMASK);
    is_bit_set!(is_shared_group, RepositoryInitMode::SHARED_GROUP);
    is_bit_set!(is_shared_all, RepositoryInitMode::SHARED_ALL);
}

/// What type of change is described by a `DiffDelta`?
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Delta {
    /// No changes
    Unmodified,
    /// Entry does not exist in old version
    Added,
    /// Entry does not exist in new version
    Deleted,
    /// Entry content changed between old and new
    Modified,
    /// Entry was renamed between old and new
    Renamed,
    /// Entry was copied from another old entry
    Copied,
    /// Entry is ignored item in workdir
    Ignored,
    /// Entry is untracked item in workdir
    Untracked,
    /// Type of entry changed between old and new
    Typechange,
    /// Entry is unreadable
    Unreadable,
    /// Entry in the index is conflicted
    Conflicted,
}

/// Valid modes for index and tree entries.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum FileMode {
    /// Unreadable
    Unreadable,
    /// Tree
    Tree,
    /// Blob
    Blob,
    /// Blob executable
    BlobExecutable,
    /// Link
    Link,
    /// Commit
    Commit,
}

impl From<FileMode> for i32 {
    fn from(mode: FileMode) -> i32 {
        match mode {
            FileMode::Unreadable => raw::GIT_FILEMODE_UNREADABLE as i32,
            FileMode::Tree => raw::GIT_FILEMODE_TREE as i32,
            FileMode::Blob => raw::GIT_FILEMODE_BLOB as i32,
            FileMode::BlobExecutable => raw::GIT_FILEMODE_BLOB_EXECUTABLE as i32,
            FileMode::Link => raw::GIT_FILEMODE_LINK as i32,
            FileMode::Commit => raw::GIT_FILEMODE_COMMIT as i32,
        }
    }
}

impl From<FileMode> for u32 {
    fn from(mode: FileMode) -> u32 {
        match mode {
            FileMode::Unreadable => raw::GIT_FILEMODE_UNREADABLE as u32,
            FileMode::Tree => raw::GIT_FILEMODE_TREE as u32,
            FileMode::Blob => raw::GIT_FILEMODE_BLOB as u32,
            FileMode::BlobExecutable => raw::GIT_FILEMODE_BLOB_EXECUTABLE as u32,
            FileMode::Link => raw::GIT_FILEMODE_LINK as u32,
            FileMode::Commit => raw::GIT_FILEMODE_COMMIT as u32,
        }
    }
}

bitflags! {
    /// Return codes for submodule status.
    ///
    /// A combination of these flags will be returned to describe the status of a
    /// submodule.  Depending on the "ignore" property of the submodule, some of
    /// the flags may never be returned because they indicate changes that are
    /// supposed to be ignored.
    ///
    /// Submodule info is contained in 4 places: the HEAD tree, the index, config
    /// files (both .git/config and .gitmodules), and the working directory.  Any
    /// or all of those places might be missing information about the submodule
    /// depending on what state the repo is in.  We consider all four places to
    /// build the combination of status flags.
    ///
    /// There are four values that are not really status, but give basic info
    /// about what sources of submodule data are available.  These will be
    /// returned even if ignore is set to "ALL".
    ///
    /// * IN_HEAD   - superproject head contains submodule
    /// * IN_INDEX  - superproject index contains submodule
    /// * IN_CONFIG - superproject gitmodules has submodule
    /// * IN_WD     - superproject workdir has submodule
    ///
    /// The following values will be returned so long as ignore is not "ALL".
    ///
    /// * INDEX_ADDED       - in index, not in head
    /// * INDEX_DELETED     - in head, not in index
    /// * INDEX_MODIFIED    - index and head don't match
    /// * WD_UNINITIALIZED  - workdir contains empty directory
    /// * WD_ADDED          - in workdir, not index
    /// * WD_DELETED        - in index, not workdir
    /// * WD_MODIFIED       - index and workdir head don't match
    ///
    /// The following can only be returned if ignore is "NONE" or "UNTRACKED".
    ///
    /// * WD_INDEX_MODIFIED - submodule workdir index is dirty
    /// * WD_WD_MODIFIED    - submodule workdir has modified files
    ///
    /// Lastly, the following will only be returned for ignore "NONE".
    ///
    /// * WD_UNTRACKED      - wd contains untracked files
    pub struct SubmoduleStatus: u32 {
        #[allow(missing_docs)]
        const IN_HEAD = raw::GIT_SUBMODULE_STATUS_IN_HEAD as u32;
        #[allow(missing_docs)]
        const IN_INDEX = raw::GIT_SUBMODULE_STATUS_IN_INDEX as u32;
        #[allow(missing_docs)]
        const IN_CONFIG = raw::GIT_SUBMODULE_STATUS_IN_CONFIG as u32;
        #[allow(missing_docs)]
        const IN_WD = raw::GIT_SUBMODULE_STATUS_IN_WD as u32;
        #[allow(missing_docs)]
        const INDEX_ADDED = raw::GIT_SUBMODULE_STATUS_INDEX_ADDED as u32;
        #[allow(missing_docs)]
        const INDEX_DELETED = raw::GIT_SUBMODULE_STATUS_INDEX_DELETED as u32;
        #[allow(missing_docs)]
        const INDEX_MODIFIED = raw::GIT_SUBMODULE_STATUS_INDEX_MODIFIED as u32;
        #[allow(missing_docs)]
        const WD_UNINITIALIZED =
                raw::GIT_SUBMODULE_STATUS_WD_UNINITIALIZED as u32;
        #[allow(missing_docs)]
        const WD_ADDED = raw::GIT_SUBMODULE_STATUS_WD_ADDED as u32;
        #[allow(missing_docs)]
        const WD_DELETED = raw::GIT_SUBMODULE_STATUS_WD_DELETED as u32;
        #[allow(missing_docs)]
        const WD_MODIFIED = raw::GIT_SUBMODULE_STATUS_WD_MODIFIED as u32;
        #[allow(missing_docs)]
        const WD_INDEX_MODIFIED =
                raw::GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED as u32;
        #[allow(missing_docs)]
        const WD_WD_MODIFIED = raw::GIT_SUBMODULE_STATUS_WD_WD_MODIFIED as u32;
        #[allow(missing_docs)]
        const WD_UNTRACKED = raw::GIT_SUBMODULE_STATUS_WD_UNTRACKED as u32;
    }
}

impl SubmoduleStatus {
    is_bit_set!(is_in_head, SubmoduleStatus::IN_HEAD);
    is_bit_set!(is_in_index, SubmoduleStatus::IN_INDEX);
    is_bit_set!(is_in_config, SubmoduleStatus::IN_CONFIG);
    is_bit_set!(is_in_wd, SubmoduleStatus::IN_WD);
    is_bit_set!(is_index_added, SubmoduleStatus::INDEX_ADDED);
    is_bit_set!(is_index_deleted, SubmoduleStatus::INDEX_DELETED);
    is_bit_set!(is_index_modified, SubmoduleStatus::INDEX_MODIFIED);
    is_bit_set!(is_wd_uninitialized, SubmoduleStatus::WD_UNINITIALIZED);
    is_bit_set!(is_wd_added, SubmoduleStatus::WD_ADDED);
    is_bit_set!(is_wd_deleted, SubmoduleStatus::WD_DELETED);
    is_bit_set!(is_wd_modified, SubmoduleStatus::WD_MODIFIED);
    is_bit_set!(is_wd_wd_modified, SubmoduleStatus::WD_WD_MODIFIED);
    is_bit_set!(is_wd_untracked, SubmoduleStatus::WD_UNTRACKED);
}

/// Submodule ignore values
///
/// These values represent settings for the `submodule.$name.ignore`
/// configuration value which says how deeply to look at the working
/// directory when getting the submodule status.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum SubmoduleIgnore {
    /// Use the submodule's configuration
    Unspecified,
    /// Any change or untracked file is considered dirty
    None,
    /// Only dirty if tracked files have changed
    Untracked,
    /// Only dirty if HEAD has moved
    Dirty,
    /// Never dirty
    All,
}

/// Submodule update values
///
/// These values represent settings for the `submodule.$name.update`
/// configuration value which says how to handle `git submodule update`
/// for this submodule. The value is usually set in the ".gitmodules"
/// file and copied to ".git/config" when the submodule is initialized.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum SubmoduleUpdate {
    /// The default; when a submodule is updated, checkout the new detached
    /// HEAD to the submodule directory.
    Checkout,
    /// Update by rebasing the current checked out branch onto the commit from
    /// the superproject.
    Rebase,
    /// Update by merging the commit in the superproject into the current
    /// checkout out branch of the submodule.
    Merge,
    /// Do not update this submodule even when the commit in the superproject
    /// is updated.
    None,
    /// Not used except as static initializer when we don't want any particular
    /// update rule to be specified.
    Default,
}

bitflags! {
    /// ...
    pub struct PathspecFlags: u32 {
        /// Use the default pathspec matching configuration.
        const DEFAULT = raw::GIT_PATHSPEC_DEFAULT as u32;
        /// Force matching to ignore case, otherwise matching will use native
        /// case sensitivity fo the platform filesystem.
        const IGNORE_CASE = raw::GIT_PATHSPEC_IGNORE_CASE as u32;
        /// Force case sensitive matches, otherwise match will use the native
        /// case sensitivity of the platform filesystem.
        const USE_CASE = raw::GIT_PATHSPEC_USE_CASE as u32;
        /// Disable glob patterns and just use simple string comparison for
        /// matching.
        const NO_GLOB = raw::GIT_PATHSPEC_NO_GLOB as u32;
        /// Means that match functions return the error code `NotFound` if no
        /// matches are found. By default no matches is a success.
        const NO_MATCH_ERROR = raw::GIT_PATHSPEC_NO_MATCH_ERROR as u32;
        /// Means that the list returned should track which patterns matched
        /// which files so that at the end of the match we can identify patterns
        /// that did not match any files.
        const FIND_FAILURES = raw::GIT_PATHSPEC_FIND_FAILURES as u32;
        /// Means that the list returned does not need to keep the actual
        /// matching filenames. Use this to just test if there were any matches
        /// at all or in combination with `PATHSPEC_FAILURES` to validate a
        /// pathspec.
        const FAILURES_ONLY = raw::GIT_PATHSPEC_FAILURES_ONLY as u32;
    }
}

impl PathspecFlags {
    is_bit_set!(is_default, PathspecFlags::DEFAULT);
    is_bit_set!(is_ignore_case, PathspecFlags::IGNORE_CASE);
    is_bit_set!(is_use_case, PathspecFlags::USE_CASE);
    is_bit_set!(is_no_glob, PathspecFlags::NO_GLOB);
    is_bit_set!(is_no_match_error, PathspecFlags::NO_MATCH_ERROR);
    is_bit_set!(is_find_failures, PathspecFlags::FIND_FAILURES);
    is_bit_set!(is_failures_only, PathspecFlags::FAILURES_ONLY);
}

impl Default for PathspecFlags {
    fn default() -> Self {
        PathspecFlags::DEFAULT
    }
}

bitflags! {
    /// Types of notifications emitted from checkouts.
    pub struct CheckoutNotificationType: u32 {
        /// Notification about a conflict.
        const CONFLICT = raw::GIT_CHECKOUT_NOTIFY_CONFLICT as u32;
        /// Notification about a dirty file.
        const DIRTY = raw::GIT_CHECKOUT_NOTIFY_DIRTY as u32;
        /// Notification about an updated file.
        const UPDATED = raw::GIT_CHECKOUT_NOTIFY_UPDATED as u32;
        /// Notification about an untracked file.
        const UNTRACKED = raw::GIT_CHECKOUT_NOTIFY_UNTRACKED as u32;
        /// Notification about an ignored file.
        const IGNORED = raw::GIT_CHECKOUT_NOTIFY_IGNORED as u32;
    }
}

impl CheckoutNotificationType {
    is_bit_set!(is_conflict, CheckoutNotificationType::CONFLICT);
    is_bit_set!(is_dirty, CheckoutNotificationType::DIRTY);
    is_bit_set!(is_updated, CheckoutNotificationType::UPDATED);
    is_bit_set!(is_untracked, CheckoutNotificationType::UNTRACKED);
    is_bit_set!(is_ignored, CheckoutNotificationType::IGNORED);
}

/// Possible output formats for diff data
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DiffFormat {
    /// full git diff
    Patch,
    /// just the headers of the patch
    PatchHeader,
    /// like git diff --raw
    Raw,
    /// like git diff --name-only
    NameOnly,
    /// like git diff --name-status
    NameStatus,
    /// git diff as used by git patch-id
    PatchId,
}

bitflags! {
    /// Formatting options for diff stats
    pub struct DiffStatsFormat: raw::git_diff_stats_format_t {
        /// Don't generate any stats
        const NONE = raw::GIT_DIFF_STATS_NONE;
        /// Equivalent of `--stat` in git
        const FULL = raw::GIT_DIFF_STATS_FULL;
        /// Equivalent of `--shortstat` in git
        const SHORT = raw::GIT_DIFF_STATS_SHORT;
        /// Equivalent of `--numstat` in git
        const NUMBER = raw::GIT_DIFF_STATS_NUMBER;
        /// Extended header information such as creations, renames and mode
        /// changes, equivalent of `--summary` in git
        const INCLUDE_SUMMARY = raw::GIT_DIFF_STATS_INCLUDE_SUMMARY;
    }
}

impl DiffStatsFormat {
    is_bit_set!(is_none, DiffStatsFormat::NONE);
    is_bit_set!(is_full, DiffStatsFormat::FULL);
    is_bit_set!(is_short, DiffStatsFormat::SHORT);
    is_bit_set!(is_number, DiffStatsFormat::NUMBER);
    is_bit_set!(is_include_summary, DiffStatsFormat::INCLUDE_SUMMARY);
}

/// Automatic tag following options.
pub enum AutotagOption {
    /// Use the setting from the remote's configuration
    Unspecified,
    /// Ask the server for tags pointing to objects we're already downloading
    Auto,
    /// Don't ask for any tags beyond the refspecs
    None,
    /// Ask for all the tags
    All,
}

/// Configuration for how pruning is done on a fetch
pub enum FetchPrune {
    /// Use the setting from the configuration
    Unspecified,
    /// Force pruning on
    On,
    /// Force pruning off
    Off,
}

#[allow(missing_docs)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StashApplyProgress {
    /// None
    None,
    /// Loading the stashed data from the object database
    LoadingStash,
    /// The stored index is being analyzed
    AnalyzeIndex,
    /// The modified files are being analyzed
    AnalyzeModified,
    /// The untracked and ignored files are being analyzed
    AnalyzeUntracked,
    /// The untracked files are being written to disk
    CheckoutUntracked,
    /// The modified files are being written to disk
    CheckoutModified,
    /// The stash was applied successfully
    Done,
}

bitflags! {
    #[allow(missing_docs)]
    pub struct StashApplyFlags: u32 {
        #[allow(missing_docs)]
        const DEFAULT = raw::GIT_STASH_APPLY_DEFAULT as u32;
        /// Try to reinstate not only the working tree's changes,
        /// but also the index's changes.
        const REINSTATE_INDEX = raw::GIT_STASH_APPLY_REINSTATE_INDEX as u32;
    }
}

impl StashApplyFlags {
    is_bit_set!(is_default, StashApplyFlags::DEFAULT);
    is_bit_set!(is_reinstate_index, StashApplyFlags::REINSTATE_INDEX);
}

impl Default for StashApplyFlags {
    fn default() -> Self {
        StashApplyFlags::DEFAULT
    }
}

bitflags! {
    #[allow(missing_docs)]
    pub struct StashFlags: u32 {
        #[allow(missing_docs)]
        const DEFAULT = raw::GIT_STASH_DEFAULT as u32;
        /// All changes already added to the index are left intact in
        /// the working directory
        const KEEP_INDEX = raw::GIT_STASH_KEEP_INDEX as u32;
        /// All untracked files are also stashed and then cleaned up
        /// from the working directory
        const INCLUDE_UNTRACKED = raw::GIT_STASH_INCLUDE_UNTRACKED as u32;
        /// All ignored files are also stashed and then cleaned up from
        /// the working directory
        const INCLUDE_IGNORED = raw::GIT_STASH_INCLUDE_IGNORED as u32;
    }
}

impl StashFlags {
    is_bit_set!(is_default, StashFlags::DEFAULT);
    is_bit_set!(is_keep_index, StashFlags::KEEP_INDEX);
    is_bit_set!(is_include_untracked, StashFlags::INCLUDE_UNTRACKED);
    is_bit_set!(is_include_ignored, StashFlags::INCLUDE_IGNORED);
}

impl Default for StashFlags {
    fn default() -> Self {
        StashFlags::DEFAULT
    }
}

bitflags! {
    #[allow(missing_docs)]
    pub struct AttrCheckFlags: u32 {
        /// Check the working directory, then the index.
        const FILE_THEN_INDEX = raw::GIT_ATTR_CHECK_FILE_THEN_INDEX as u32;
        /// Check the index, then the working directory.
        const INDEX_THEN_FILE = raw::GIT_ATTR_CHECK_INDEX_THEN_FILE as u32;
        /// Check the index only.
        const INDEX_ONLY = raw::GIT_ATTR_CHECK_INDEX_ONLY as u32;
        /// Do not use the system gitattributes file.
        const NO_SYSTEM = raw::GIT_ATTR_CHECK_NO_SYSTEM as u32;
    }
}

impl Default for AttrCheckFlags {
    fn default() -> Self {
        AttrCheckFlags::FILE_THEN_INDEX
    }
}

bitflags! {
    #[allow(missing_docs)]
    pub struct DiffFlags: u32 {
        /// File(s) treated as binary data.
        const BINARY = raw::GIT_DIFF_FLAG_BINARY as u32;
        /// File(s) treated as text data.
        const NOT_BINARY = raw::GIT_DIFF_FLAG_NOT_BINARY as u32;
        /// `id` value is known correct.
        const VALID_ID = raw::GIT_DIFF_FLAG_VALID_ID as u32;
        /// File exists at this side of the delta.
        const EXISTS = raw::GIT_DIFF_FLAG_EXISTS as u32;
    }
}

impl DiffFlags {
    is_bit_set!(is_binary, DiffFlags::BINARY);
    is_bit_set!(is_not_binary, DiffFlags::NOT_BINARY);
    is_bit_set!(has_valid_id, DiffFlags::VALID_ID);
    is_bit_set!(exists, DiffFlags::EXISTS);
}

bitflags! {
    /// Options for [`Reference::normalize_name`].
    pub struct ReferenceFormat: u32 {
        /// No particular normalization.
        const NORMAL = raw::GIT_REFERENCE_FORMAT_NORMAL as u32;
        /// Constrol whether one-level refname are accepted (i.e., refnames that
        /// do not contain multiple `/`-separated components). Those are
        /// expected to be written only using uppercase letters and underscore
        /// (e.g. `HEAD`, `FETCH_HEAD`).
        const ALLOW_ONELEVEL = raw::GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL as u32;
        /// Interpret the provided name as a reference pattern for a refspec (as
        /// used with remote repositories). If this option is enabled, the name
        /// is allowed to contain a single `*` in place of a full pathname
        /// components (e.g., `foo/*/bar` but not `foo/bar*`).
        const REFSPEC_PATTERN = raw::GIT_REFERENCE_FORMAT_REFSPEC_PATTERN as u32;
        /// Interpret the name as part of a refspec in shorthand form so the
        /// `ALLOW_ONELEVEL` naming rules aren't enforced and `main` becomes a
        /// valid name.
        const REFSPEC_SHORTHAND = raw::GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND as u32;
    }
}

impl ReferenceFormat {
    is_bit_set!(is_allow_onelevel, ReferenceFormat::ALLOW_ONELEVEL);
    is_bit_set!(is_refspec_pattern, ReferenceFormat::REFSPEC_PATTERN);
    is_bit_set!(is_refspec_shorthand, ReferenceFormat::REFSPEC_SHORTHAND);
}

impl Default for ReferenceFormat {
    fn default() -> Self {
        ReferenceFormat::NORMAL
    }
}

#[cfg(test)]
mod tests {
    use super::{FileMode, ObjectType};

    #[test]
    fn convert() {
        assert_eq!(ObjectType::Blob.str(), "blob");
        assert_eq!(ObjectType::from_str("blob"), Some(ObjectType::Blob));
        assert!(ObjectType::Blob.is_loose());
    }

    #[test]
    fn convert_filemode() {
        assert_eq!(i32::from(FileMode::Blob), 0o100644);
        assert_eq!(i32::from(FileMode::BlobExecutable), 0o100755);
        assert_eq!(u32::from(FileMode::Blob), 0o100644);
        assert_eq!(u32::from(FileMode::BlobExecutable), 0o100755);
    }
}
