/*
 * libgit2 "general" example - shows basic libgit2 concepts
 *
 * Written by the libgit2 contributors
 *
 * To the extent possible under law, the author(s) have dedicated all copyright
 * and related and neighboring rights to this software to the public domain
 * worldwide. This software is distributed without any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication along
 * with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

// [**libgit2**][lg] is a portable, pure C implementation of the Git core
// methods provided as a re-entrant linkable library with a solid API,
// allowing you to write native speed custom Git applications in any
// language which supports C bindings.
//
// This file is an example of using that API in a real, compilable C file.
// As the API is updated, this file will be updated to demonstrate the new
// functionality.
//
// If you're trying to write something in C using [libgit2][lg], you should
// also check out the generated [API documentation][ap]. We try to link to
// the relevant sections of the API docs in each section in this file.
//
// **libgit2** (for the most part) only implements the core plumbing
// functions, not really the higher level porcelain stuff. For a primer on
// Git Internals that you will need to know to work with Git at this level,
// check out [Chapter 9][pg] of the Pro Git book.
//
// [lg]: http://libgit2.github.com
// [ap]: http://libgit2.github.com/libgit2
// [pg]: http://progit.org/book/ch9-0.html

// ### Includes

// Including the `git2.h` header will include all the other libgit2 headers
// that you need.  It should be the only thing you need to include in order
// to compile properly and get all the libgit2 API.
#include <git2.h>
#include <stdio.h>

// Almost all libgit2 functions return 0 on success or negative on error.
// This is not production quality error checking, but should be sufficient
// as an example.
static void check_error(int error_code, const char *action)
{
	if (!error_code)
		return;

	const git_error *error = giterr_last();

	printf("Error %d %s - %s\n", error_code, action,
		   (error && error->message) ? error->message : "???");

	exit(1);
}

int main (int argc, char** argv)
{
  // ### Opening the Repository

  // There are a couple of methods for opening a repository, this being the
  // simplest.  There are also [methods][me] for specifying the index file
  // and work tree locations, here we assume they are in the normal places.
	//
	// (Try running this program against tests/resources/testrepo.git.)
  //
  // [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository
  int error;
  const char *repo_path = (argc > 1) ? argv[1] : "/opt/libgit2-test/.git";
  git_repository *repo;

  error = git_repository_open(&repo, repo_path);
  check_error(error, "opening repository");

  // ### SHA-1 Value Conversions

  // For our first example, we will convert a 40 character hex value to the
  // 20 byte raw SHA1 value.
  printf("*Hex to Raw*\n");
  char hex[] = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";

  // The `git_oid` is the structure that keeps the SHA value. We will use
  // this throughout the example for storing the value of the current SHA
  // key we're working with.
  git_oid oid;
  git_oid_fromstr(&oid, hex);

  // Once we've converted the string into the oid value, we can get the raw
  // value of the SHA by accessing `oid.id`

  // Next we will convert the 20 byte raw SHA1 value to a human readable 40
  // char hex value.
  printf("\n*Raw to Hex*\n");
  char out[41];
  out[40] = '\0';

  // If you have a oid, you can easily get the hex value of the SHA as well.
  git_oid_fmt(out, &oid);
  printf("SHA hex string: %s\n", out);

  // ### Working with the Object Database

  // **libgit2** provides [direct access][odb] to the object database.  The
  // object database is where the actual objects are stored in Git. For
  // working with raw objects, we'll need to get this structure from the
  // repository.
  //
  // [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb
  git_odb *odb;
  git_repository_odb(&odb, repo);

  // #### Raw Object Reading

  printf("\n*Raw Object Read*\n");
  git_odb_object *obj;
  git_otype otype;
  const unsigned char *data;
  const char *str_type;

  // We can read raw objects directly from the object database if we have
  // the oid (SHA) of the object.  This allows us to access objects without
  // knowing thier type and inspect the raw bytes unparsed.
  error = git_odb_read(&obj, odb, &oid);
  check_error(error, "finding object in repository");

  // A raw object only has three properties - the type (commit, blob, tree
  // or tag), the size of the raw data and the raw, unparsed data itself.
  // For a commit or tag, that raw data is human readable plain ASCII
  // text. For a blob it is just file contents, so it could be text or
  // binary data. For a tree it is a special binary format, so it's unlikely
  // to be hugely helpful as a raw object.
  data = (const unsigned char *)git_odb_object_data(obj);
  otype = git_odb_object_type(obj);

  // We provide methods to convert from the object type which is an enum, to
  // a string representation of that value (and vice-versa).
  str_type = git_object_type2string(otype);
  printf("object length and type: %d, %s\n",
      (int)git_odb_object_size(obj),
      str_type);

  // For proper memory management, close the object when you are done with
  // it or it will leak memory.
  git_odb_object_free(obj);

  // #### Raw Object Writing

  printf("\n*Raw Object Write*\n");

  // You can also write raw object data to Git. This is pretty cool because
  // it gives you direct access to the key/value properties of Git.  Here
  // we'll write a new blob object that just contains a simple string.
  // Notice that we have to specify the object type as the `git_otype` enum.
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);

  // Now that we've written the object, we can check out what SHA1 was
  // generated when the object was written to our database.
  git_oid_fmt(out, &oid);
  printf("Written Object: %s\n", out);

  // ### Object Parsing

  // libgit2 has methods to parse every object type in Git so you don't have
  // to work directly with the raw data. This is much faster and simpler
  // than trying to deal with the raw data yourself.

  // #### Commit Parsing

  // [Parsing commit objects][pco] is simple and gives you access to all the
  // data in the commit - the author (name, email, datetime), committer
  // (same), tree, message, encoding and parent(s).
  //
  // [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit

  printf("\n*Commit Parsing*\n");

  git_commit *commit;
  git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479");

  error = git_commit_lookup(&commit, repo, &oid);
  check_error(error, "looking up commit");

  const git_signature *author, *cmtter;
  const char *message;
  time_t ctime;
  unsigned int parents, p;

  // Each of the properties of the commit object are accessible via methods,
  // including commonly needed variations, such as `git_commit_time` which
  // returns the author time and `git_commit_message` which gives you the
  // commit message (as a NUL-terminated string).
  message  = git_commit_message(commit);
  author   = git_commit_author(commit);
  cmtter   = git_commit_committer(commit);
  ctime    = git_commit_time(commit);

  // The author and committer methods return [git_signature] structures,
  // which give you name, email and `when`, which is a `git_time` structure,
  // giving you a timestamp and timezone offset.
  printf("Author: %s (%s)\n", author->name, author->email);

  // Commits can have zero or more parents. The first (root) commit will
  // have no parents, most commits will have one (i.e. the commit it was
  // based on) and merge commits will have two or more.  Commits can
  // technically have any number, though it's rare to have more than two.
  parents  = git_commit_parentcount(commit);
  for (p = 0;p < parents;p++) {
    git_commit *parent;
    git_commit_parent(&parent, commit, p);
    git_oid_fmt(out, git_commit_id(parent));
    printf("Parent: %s\n", out);
    git_commit_free(parent);
  }

  // Don't forget to close the object to prevent memory leaks. You will have
  // to do this for all the objects you open and parse.
  git_commit_free(commit);

  // #### Writing Commits

  // libgit2 provides a couple of methods to create commit objects easily as
  // well. There are four different create signatures, we'll just show one
  // of them here.  You can read about the other ones in the [commit API
  // docs][cd].
  //
  // [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit

  printf("\n*Commit Writing*\n");
  git_oid tree_id, parent_id, commit_id;
  git_tree *tree;
  git_commit *parent;

  // Creating signatures for an authoring identity and time is simple.  You
  // will need to do this to specify who created a commit and when.  Default
  // values for the name and email should be found in the `user.name` and
  // `user.email` configuration options.  See the `config` section of this
  // example file to see how to access config values.
  git_signature_new((git_signature **)&author,
      "Scott Chacon", "schacon@gmail.com", 123456789, 60);
  git_signature_new((git_signature **)&cmtter,
      "Scott A Chacon", "scott@github.com", 987654321, 90);

  // Commit objects need a tree to point to and optionally one or more
  // parents.  Here we're creating oid objects to create the commit with,
  // but you can also use
  git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
  git_tree_lookup(&tree, repo, &tree_id);
  git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
  git_commit_lookup(&parent, repo, &parent_id);

  // Here we actually create the commit object with a single call with all
  // the values we need to create the commit.  The SHA key is written to the
  // `commit_id` variable here.
  git_commit_create_v(
    &commit_id, /* out id */
    repo,
    NULL, /* do not update the HEAD */
    author,
    cmtter,
    NULL, /* use default message encoding */
    "example commit",
    tree,
    1, parent);

  // Now we can take a look at the commit SHA we've generated.
  git_oid_fmt(out, &commit_id);
  printf("New Commit: %s\n", out);

  // #### Tag Parsing

  // You can parse and create tags with the [tag management API][tm], which
  // functions very similarly to the commit lookup, parsing and creation
  // methods, since the objects themselves are very similar.
  //
  // [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag
  printf("\n*Tag Parsing*\n");
  git_tag *tag;
  const char *tmessage, *tname;
  git_otype ttype;

  // We create an oid for the tag object if we know the SHA and look it up
  // the same way that we would a commit (or any other object).
  git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");

  error = git_tag_lookup(&tag, repo, &oid);
  check_error(error, "looking up tag");

  // Now that we have the tag object, we can extract the information it
  // generally contains: the target (usually a commit object), the type of
  // the target object (usually 'commit'), the name ('v1.0'), the tagger (a
  // git_signature - name, email, timestamp), and the tag message.
  git_tag_target((git_object **)&commit, tag);
  tname = git_tag_name(tag);		// "test"
  ttype = git_tag_target_type(tag);	// GIT_OBJ_COMMIT (otype enum)
  tmessage = git_tag_message(tag);	// "tag message\n"
  printf("Tag Message: %s\n", tmessage);

  git_commit_free(commit);

  // #### Tree Parsing

  // [Tree parsing][tp] is a bit different than the other objects, in that
  // we have a subtype which is the tree entry.  This is not an actual
  // object type in Git, but a useful structure for parsing and traversing
  // tree entries.
  //
  // [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree
  printf("\n*Tree Parsing*\n");

  const git_tree_entry *entry;
  git_object *objt;

  // Create the oid and lookup the tree object just like the other objects.
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
  git_tree_lookup(&tree, repo, &oid);

  // Getting the count of entries in the tree so you can iterate over them
  // if you want to.
  size_t cnt = git_tree_entrycount(tree); // 3
  printf("tree entries: %d\n", (int)cnt);

  entry = git_tree_entry_byindex(tree, 0);
  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"

  // You can also access tree entries by name if you know the name of the
  // entry you're looking for.
  entry = git_tree_entry_byname(tree, "README");
  git_tree_entry_name(entry); // "hello.c"

  // Once you have the entry object, you can access the content or subtree
  // (or commit, in the case of submodules) that it points to.  You can also
  // get the mode if you want.
  git_tree_entry_to_object(&objt, repo, entry); // blob

  // Remember to close the looked-up object once you are done using it
  git_object_free(objt);

  // #### Blob Parsing

  // The last object type is the simplest and requires the least parsing
  // help. Blobs are just file contents and can contain anything, there is
  // no structure to it. The main advantage to using the [simple blob
  // api][ba] is that when you're creating blobs you don't have to calculate
  // the size of the content.  There is also a helper for reading a file
  // from disk and writing it to the db and getting the oid back so you
  // don't have to do all those steps yourself.
  //
  // [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob

  printf("\n*Blob Parsing*\n");
  git_blob *blob;

  git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08");
  git_blob_lookup(&blob, repo, &oid);

  // You can access a buffer with the raw contents of the blob directly.
  // Note that this buffer may not be contain ASCII data for certain blobs
  // (e.g. binary files): do not consider the buffer a NULL-terminated
  // string, and use the `git_blob_rawsize` attribute to find out its exact
  // size in bytes
  printf("Blob Size: %ld\n", (long)git_blob_rawsize(blob)); // 8
  git_blob_rawcontent(blob); // "content"

  // ### Revwalking

  // The libgit2 [revision walking api][rw] provides methods to traverse the
  // directed graph created by the parent pointers of the commit objects.
  // Since all commits point back to the commit that came directly before
  // them, you can walk this parentage as a graph and find all the commits
  // that were ancestors of (reachable from) a given starting point.  This
  // can allow you to create `git log` type functionality.
  //
  // [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk

  printf("\n*Revwalking*\n");
  git_revwalk *walk;
  git_commit *wcommit;

  git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644");

  // To use the revwalker, create a new walker, tell it how you want to sort
  // the output and then push one or more starting points onto the walker.
  // If you want to emulate the output of `git log` you would push the SHA
  // of the commit that HEAD points to into the walker and then start
  // traversing them.  You can also 'hide' commits that you want to stop at
  // or not see any of their ancestors.  So if you want to emulate `git log
  // branch1..branch2`, you would push the oid of `branch2` and hide the oid
  // of `branch1`.
  git_revwalk_new(&walk, repo);
  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
  git_revwalk_push(walk, &oid);

  const git_signature *cauth;
  const char *cmsg;

  // Now that we have the starting point pushed onto the walker, we start
  // asking for ancestors. It will return them in the sorting order we asked
  // for as commit oids.  We can then lookup and parse the commited pointed
  // at by the returned OID; note that this operation is specially fast
  // since the raw contents of the commit object will be cached in memory
  while ((git_revwalk_next(&oid, walk)) == 0) {
    error = git_commit_lookup(&wcommit, repo, &oid);
	check_error(error, "looking up commit during revwalk");

    cmsg  = git_commit_message(wcommit);
    cauth = git_commit_author(wcommit);
    printf("%s (%s)\n", cmsg, cauth->email);

    git_commit_free(wcommit);
  }

  // Like the other objects, be sure to free the revwalker when you're done
  // to prevent memory leaks.  Also, make sure that the repository being
  // walked it not deallocated while the walk is in progress, or it will
  // result in undefined behavior
  git_revwalk_free(walk);

  // ### Index File Manipulation

  // The [index file API][gi] allows you to read, traverse, update and write
  // the Git index file (sometimes thought of as the staging area).
  //
  // [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index

  printf("\n*Index Walking*\n");

  git_index *index;
  unsigned int i, ecount;

  // You can either open the index from the standard location in an open
  // repository, as we're doing here, or you can open and manipulate any
  // index file with `git_index_open_bare()`. The index for the repository
  // will be located and loaded from disk.
  git_repository_index(&index, repo);

  // For each entry in the index, you can get a bunch of information
  // including the SHA (oid), path and mode which map to the tree objects
  // that are written out.  It also has filesystem properties to help
  // determine what to inspect for changes (ctime, mtime, dev, ino, uid,
  // gid, file_size and flags) All these properties are exported publicly in
  // the `git_index_entry` struct
  ecount = git_index_entrycount(index);
  for (i = 0; i < ecount; ++i) {
    const git_index_entry *e = git_index_get_byindex(index, i);

    printf("path: %s\n", e->path);
    printf("mtime: %d\n", (int)e->mtime.seconds);
    printf("fs: %d\n", (int)e->file_size);
  }

  git_index_free(index);

  // ### References

  // The [reference API][ref] allows you to list, resolve, create and update
  // references such as branches, tags and remote references (everything in
  // the .git/refs directory).
  //
  // [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference

  printf("\n*Reference Listing*\n");

  // Here we will implement something like `git for-each-ref` simply listing
  // out all available references and the object SHA they resolve to.
  git_strarray ref_list;
  git_reference_list(&ref_list, repo);

  const char *refname;
  git_reference *ref;

  // Now that we have the list of reference names, we can lookup each ref
  // one at a time and resolve them to the SHA, then print both values out.
  for (i = 0; i < ref_list.count; ++i) {
    refname = ref_list.strings[i];
    git_reference_lookup(&ref, repo, refname);

    switch (git_reference_type(ref)) {
    case GIT_REF_OID:
      git_oid_fmt(out, git_reference_target(ref));
      printf("%s [%s]\n", refname, out);
      break;

    case GIT_REF_SYMBOLIC:
      printf("%s => %s\n", refname, git_reference_symbolic_target(ref));
      break;
    default:
      fprintf(stderr, "Unexpected reference type\n");
      exit(1);
    }
  }

  git_strarray_free(&ref_list);

  // ### Config Files

  // The [config API][config] allows you to list and updatee config values
  // in any of the accessible config file locations (system, global, local).
  //
  // [config]: http://libgit2.github.com/libgit2/#HEAD/group/config

  printf("\n*Config Listing*\n");

  const char *email;
  int32_t j;

  git_config *cfg;

  // Open a config object so we can read global values from it.
  char config_path[256];
  sprintf(config_path, "%s/config", repo_path);
  check_error(git_config_open_ondisk(&cfg, config_path), "opening config");

  git_config_get_int32(&j, cfg, "help.autocorrect");
  printf("Autocorrect: %d\n", j);

  git_config_get_string(&email, cfg, "user.email");
  printf("Email: %s\n", email);

  // Finally, when you're done with the repository, you can free it as well.
  git_repository_free(repo);

  return 0;
}

