var exec = require('sync-exec');
var exit = 0;
var glob = require("glob");
var globOptions = {
  ignore: [
    'bower_components/**/*',
    'node_modules/**/*'
  ]
};

var pkg = require('../../package');
// Change to \{{ hook }} once that variable is available.
// @see https://github.com/wecodemore/grunt-githooks/pull/40
var hooks = pkg.githooks && pkg.githooks['{{ task }}'];
if (hooks) {
  var ret, hook, files, commands, staged, matchAll;
  var filesMatched = [];

  // Iterate over all hook definitions.
  for (var h in hooks) {
    hook = hooks[h];
    commands = hook.commands || [];
    staged = hook.staged === void 0 ? false : !!hook.staged;
    matchAll = hook.matchAll === void 0 ? true : !!hook.matchAll;

    // Iterate over all files in a hook definition.
    if (hook.files) {
      // Expand all file paths using glob (for pattern matching).
      if (typeof hook.files === 'string') {
        files = glob.sync(hook.files, globOptions) || [];
      }
      if (Array.isArray(hook.files)) {
        files = [];
        for (var f = 0; f < hook.files.length; f++) {
          files = [].concat(files, glob.sync(hook.files[f], globOptions) || []);
        }
      }

      // All files must either be staged or modified for the entire
      // hook definition command(s) to be executed.
      for (f in files) {
        var file = files[f];
        if (file) {
          // Only continue if file has been staged or modified.
          ret = exec((staged ? 'git diff --name-only --cached ' + file : 'git diff HEAD@{1} --stat -- ' + file));
          exit = ret.status;
          if (exit === 0 && ret.stdout !== '') {
            filesMatched.push(file);
          }
          else if (matchAll && (exit > 0 || ret.stdout === '')) {
            console.log(ret.stdout);
            filesMatched = [];
            break;
          }
        }
      }
    }

    // Iterate over all commands that should be executed for matched files.
    if (filesMatched.length) {
      if (typeof commands === 'string') {
        commands = [commands];
      }
      for (var c in commands) {
        var command = commands[c];
        console.log("\033[4;35mgit: {{ task }}\033[0;35m\n>> " + command + "\033[0m\n");
        ret = exec(command);
        console.log(ret.stdout);
        exit = ret.status;
        if (exit > 0) {
          break;
        }
      }
    }

    // Display any errors.
    if (exit > 0 && ret && ret.stderr) {
      console.log(ret.stderr);
    }
  }
}

process.exit(exit);
