var git = require("git-promise");
var gitUtil = require("git-promise/util");
var parseOut = require("./output");
var DEFAULT_BRANCH = "origin/master";

exports.__set_git__ = function (mock) {
	git = mock;
};

exports.fetch = function (summary) {
	// No need to process the output
	return git("fetch --all --prune --quiet", function () {
		return summary;
	});
};

exports.getStatus = function (summary) {
	return git("status -sbz --porcelain", function (output) {
		var status = gitUtil.extractStatus(output);

		summary.branch = status.branch;
		summary.index = status.index;
		summary.workingTree = status.workingTree;

		return summary;
	});
};

exports.checkFastForward = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git("merge-base --is-ancestor " + branch + " HEAD", function (output, code) {
		if (code === 0) {
			summary.fastForward = true;
		} else if (code === 1) {
			summary.fastForward = false;
		} else {
			throw new Error("Unable to determine whether HEAD is fast forward with " + branch);
		}
		return summary;
	});
};

exports.baseCommit = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git("merge-base " + branch + " HEAD", function (output) {
		summary.baseCommit = output.trim();
		return summary;
	});
};

exports.hasConflict = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git("merge-tree " + summary.baseCommit + " " + branch + " HEAD", function (output) {
		summary.hasConflict = gitUtil.hasConflict(output);
		return summary;
	});
};

exports.localChanges = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git([
		"log " + branch + "..HEAD",
		"--date=local --date-order --reverse",
		"--pretty=\"format:COMMIT%nauthor:%an%nemail:%ae%ndate:%ad%nrelativeDate:%ar%nsubject:%s%n%x00>>>>BODY>>>>%+b%n%x00<<<</BODY<<<<\"",
		"--numstat --shortstat --summary"
	].join(" "), function (output) {
		summary.localChanges = parseOut.listChanges(output);
		return summary;
	});
};

exports.remoteChanges = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git([
		"log " + summary.baseCommit + ".." + branch,
		"--date=local --date-order --reverse",
		"--pretty=\"format:COMMIT%nauthor:%an%nemail:%ae%ndate:%ad%nrelativeDate:%ar%nsubject:%s%n%x00>>>>BODY>>>>%+b%n%x00<<<</BODY<<<<\"",
		"--numstat --shortstat --summary"
	].join(" "), function (output) {
		summary.remoteChanges = parseOut.listChanges(output);
		return summary;
	});
};

exports.mergedBranches = function (summary) {
	var branch = summary.referenceBranch || DEFAULT_BRANCH;
	return git("branch --merged " + branch, function (output) {
		summary.mergedBranches = output.split("\n").filter(function (line) {
			return !!line.trim();
		}).map(function (line) {
			return line.trim();
		});
		return summary;
	});
};
