"use strict";

/* eslint no-process-exit:0 */

var fs = require("fs");
var path = require("path");

var git = require("../git");


var templates = path.join(__dirname, "..", "..", "doc", "hooks");
var prePushCommand = fs.readFileSync(path.join(templates, "command.txt"), {encoding: "utf8"}).trim();
var prePushTxt = fs.readFileSync(path.join(templates, "pre-push.txt"), {encoding: "utf8"});
var prePushScript = prePushTxt.replace(/\{\s*command\s*\}/g, prePushCommand);

exports.config = function (opts) {
  return opts
    .boolean("u")
    .alias("u", "uninstall")
    .describe("u", "Uninstall Github-Todos hook")
    .boolean("f")
    .alias("f", "force")
    .describe("f", "Force-delete hook on uninstall, or force-add command to existing hook on install");
};

exports.run = function (argv) {
  git.dir("hooks/pre-push", function (err, file) {
    if (err) {
      throw err;
    }

    var found = fs.existsSync(file);
    var content = found && fs.readFileSync(file, {encoding: "utf8"});
    var isUnmodifiedScript = content && (content.trim() === prePushScript.trim());
    var commandFound = content && content.indexOf(prePushCommand) !== -1;

    if (argv.uninstall) {
      if (isUnmodifiedScript || argv.force) {
        removeHook(file);
      } else if (content && commandFound) {
        removeFromHook(file, content);
      } else {
        cannotUninstall(file, content);
      }
    } else {
      if (commandFound && !argv.force) {
        commandAlreadyInHook(file);
      } else if (found) {
        addToHook(file, content, commandFound);
      } else {
        createHook(file);
      }
    }

    if (!argv.uninstall) {
      try {
        fs.chmodSync(file, 493); // 0755
      } catch (e) {
        console.error("WARNING: Failed to `chmod 755 " + file + "`. Not that this file *must* be executable, you may want to fix this manually.");
      }
    }

    console.log("OK.");
  });
};


function createHook (file) {
  console.log("Hook file not found, create new one…");
  fs.writeFileSync(file, prePushScript);
}

function addToHook (file, content, unsafe) {
  if (unsafe) {
    console.error("Hook file found, github-todos command found.");
    console.error("Execution forced by option --force: add github-todos command on top anyway…");
  } else {
    console.log("Hook file found, add github-todos command on top…");
  }

  var lines = content.split("\n");
  lines.splice(1, 0, "\n" + prePushCommand + "\n");
  content = lines.join("\n");

  fs.writeFileSync(file, content);
}

function removeFromHook (file, content) {
  console.log("Hook file found, removing github-todos command…");

  content = content.split("\n").map(function (line, index) {
    if (line.indexOf(prePushCommand) !== -1) {
      console.log("Remove line " + (index + 1) + ": " + line);
      return "";
    }

    return line;
  }).join("\n");

  fs.writeFileSync(file, content);
}

function removeHook (file) {
  console.log("Hook file found, unmodified, remove hook…");

  fs.unlinkSync(file);
}

function commandAlreadyInHook (file) {
  console.error("Hook file found, github-todos command found.");
  console.error("Use option --force to add command to hook anyway.");
  console.error("You may want to insert command '" + prePushCommand + "' manually: edit '" + file + "'");

  process.exit(5);
}

function cannotUninstall (file, hasContent) {
  if (hasContent) {
    console.error("Hook file found but command not found, cannot uninstall.");
  } else {
    console.error("Hook file not found, cannot uninstall.");
  }
  console.error("You may want to uninstall manually: edit '" + file + "'");

  process.exit(5);
}

@@ -96,34 +96,161 @@
 %22);%0A
-%0Avar git = require(%22../git
+var async = require(%22async%22);%0Avar _ = require(%22lodash%22);%0A%0Avar git = require(%22../git%22);%0Avar github = require(%22../github%22);%0Avar config = require(%22../config
 %22);%0A
@@ -881,16 +881,171 @@
 nstall%22)
+%0A    .boolean(%22connect%22)%0A    .default(%22connect%22, true)%0A    .describe(%22connect%22, %22Check or create Github authentication credentials before generating hook%22)
 ;%0A%7D;%0A%0Aex
@@ -1080,16 +1080,51 @@
 %7B%0A  
+var ops = %7B%0A    %22path%22: _.partial(
 git.dir
-(
+, 
 %22hoo
@@ -1139,29 +1139,345 @@
 ush%22
-, function (err, file
+)%0A  %7D;%0A%0A  if (argv.connect) %7B%0A    console.log(%22To disable checking credentials on 'init', add option '--no-connect'%22);%0A    ops.connect = function (cb) %7B%0A      config.list(function (err, conf) %7B%0A        if (err) %7B%0A          throw err;%0A        %7D%0A%0A        github.connect(conf, cb);%0A      %7D);%0A    %7D;%0A  %7D%0A%0A  async.auto(ops, function (err, res
 ) %7B%0A
@@ -1511,24 +1511,49 @@
 err;%0A    %7D%0A%0A
+    var file = res.path;%0A
     var foun

Connect to Github on 'github-todos init'