(ns ^{:go-imports []
      :doc "Provides API for accessing and manipulating git repositories."}
  git)

(defn ^GitRepo open
  "Opens a git repository from the given path. It detects if the
   repository is bare or a normal one. Throws an error if the path doesn't contain a valid repository."
  {:added "1.3"
   :go "open(path)"}
  [^String path])

(defn config
  "Returns git repo's config"
  {:added "1.3"
   :go "config(repo)"}
  [^GitRepo repo])

(defn ref
  "Returns the reference for a given reference name. If resolved is
   true, any symbolic reference will be resolved."
  {:added "1.3"
   :go "ref(repo, name, resolved)"}
  [^GitRepo repo, ^String name, ^Boolean resolved])

(defn head
  "Returns the reference where HEAD is pointing to."
  {:added "1.3"
   :go "head(repo)"}
  [^GitRepo repo])

(defn log
  "Returns the commit history from the given opts.
  opts may have the following keys:

  :from - when the from option is set the log will only contain commits
  reachable from it. If this option is not set, HEAD will be used as
  the default from.

  :order - the default traversal algorithm is depth-first search.
  Set order to :committer-time for ordering by committer time (more compatible with `git log`).
  Set order to :bsf for breadth-first search

  :path-filter - filter commits based on the path of files that are updated.
  Takes file path as argument and should return true if the file is desired.
  It can be used to implement `git log -- <path>`.
  Either <path> is a file path, or directory path, or a regexp of file/directory path.

  :all - pretend as if all the refs in refs/, along with HEAD, are listed on the command line as <commit>.
  It is equivalent to running `git log --all`.
  If set to true, the :from option will be ignored.

  :since - show commits more recent than a specific date.
  It is equivalent to running `git log --since <date>` or `git log --after <date>`.

  :until - show commits older than a specific date.
  It is equivalent to running `git log --until <date>` or `git log --before <date>`.
"
  {:added "1.3"
   :go "log(repo, opts)"}
  [^GitRepo repo ^Map opts])

(defn ^String resolve-revision
  "Resolves revision to corresponding hash. It will always
   resolve to a commit hash, not a tree or annotated tag."
  {:added "1.3"
   :go "resolveRevision(repo, revision)"}
  [^GitRepo repo ^String revision])

(defn object
  "Returns an Object with the given hash."
  {:added "1.3"
   :go "findObject(repo, hash)"}
  [^GitRepo repo ^String hash])

(defn commit
  "Returns a commit with the given hash."
  {:added "1.3"
   :go "findCommit(repo, hash)"}
  [^GitRepo repo ^String hash])

(defn ^String add-path
  "Adds the file contents of a file in the worktree to the index. If the
   file is already staged in the index no error is thrown. If a file deleted
   from the workspace is given, the file is removed from the index. If a
   directory given, adds the files and all his sub-directories recursively in
   the worktree to the index. If any of the files is already staged in the index
   no error is thrown. When path is a file, the hash is returned."
  {:added "1.4"
   :go "addPath(repo, path)"}
  [^GitRepo repo ^String path])

(defn ^String add-commit
  "Stores the current contents of the index in a new commit along with
   a log message from the user describing the changes."
  {:added "1.4"
   :go "addCommit(repo, msg, opts)"}
  [^GitRepo repo ^String msg ^Map opts])
