import crypto from 'crypto';
import path from 'path';

import { Repository, FetchOptions, Clone, CloneOptions } from 'nodegit';
import { rimraf, mkdirp } from './promisify';

const d = require('debug')('serf:git-api');

export async function cloneRepo(url, targetDirname, token=null, bare=true) {
  let opts = new CloneOptions();
  opts.bare = bare ? 1 : 0;

  await Clone.clone(url, targetDirname, opts);
}

export async function fetchRepo(targetDirname, token=null) {
  let repo = await Repository.openBare(targetDirname);
  await repo.fetchAll(new FetchOptions());
}

export async function cloneOrFetchRepo(url, checkoutDir, token=null) {
  let dirname = crypto.createHash('sha1').update(url).digest('hex');
  let targetDirname = path.join(checkoutDir, dirname);

  try {
    await fetchRepo(targetDirname, token);
    return targetDirname;
  } catch (e) {
    console.error(`Failed to open bare repository, going to clone instead: ${e.message}`);
    d(e.stack);
  }

  await rimraf(targetDirname);
  await mkdirp(targetDirname);

  await cloneRepo(url, targetDirname, token);
  return targetDirname;
}

@@ -102,16 +102,43 @@
 eOptions
+, Checkout, CheckoutOptions
  %7D from 
@@ -240,16 +240,675 @@
 api');%0A%0A
+export async function getHeadForRepo(targetDirname) %7B%0A  let repo = await Repository.open(targetDirname);%0A  let commit = await repo.getHeadCommit();%0A%0A  return commit.sha;%0A%7D%0A%0Aexport async function checkoutSha(targetDirname, sha) %7B%0A  let repo = await Repository.open(targetDirname);%0A  let commit = await repo.getCommit(sha);%0A%0A  let opts = new CheckoutOptions();%0A%0A  // Equivalent of %60git reset --hard HEAD && git clean -xdf%60%0A  opts.checkoutStrategy = opts.checkoutStrategy %7C%0A    Checkout.STRATEGY.FORCE %7C%0A    Checkout.STRATEGY.REMOVE_UNTRACKED %7C%0A    Checkout.STRATEGY.USE_THEIRS %7C%0A    Checkout.STRATEGY.UPDATE_SUBMODULES;%0A%0A  await Checkout.tree(repo, commit);%0A%7D%0A%0A
 export a

Add some more helpful Git methods