/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

var path = require('path');
var executil = require('./executil');
var gitutil = exports;
var semver = require('semver');

/**
 * Returns the greatest semver-looking tag in the repo. If prefix is specified, only looks at tags that start with
 * 'prefix-' (this allows for multiple modules in the same repo).
 * @param {string} [prefix] - An optional prefix to filter tags.
 * @returns {Array} - the most recent tag as as the 0th index in an array (with the second recent as the next index), or null if no version tags are found.
 * ignores r tags in plugins
 */
exports.findMostRecentTag = function*(prefix) {
    prefix = prefix && prefix + "-";
    var finalBest;
    var lastBest;

    var ret = (yield executil.execHelper(executil.ARGS('git tag --list'), true)).split(/\s+/)
        .reduce(function (curBest, value) {
            var modifiedCurBest, modifiedValue;
            if (prefix) {
                // Ignore values that don't start with prefix, and strip prefix from the value we're going to test
                if (value.indexOf(prefix) !== 0 ) {
                    modifiedValue = null;
                    modifiedCurBest = null;
                } else {
                    modifiedValue = value.substr(prefix.length);
                    modifiedCurBest = curBest && curBest.substr(prefix.length);
                }
            } else {
                //used to strip out r for plugins, but now leave it in so they fail semver check
                modifiedCurBest = curBest;
                modifiedValue = value;
            }

            if (semver.valid(modifiedValue)) {
                //use finalBest to hold onto reference outside of reduce function
                finalBest = !curBest ? value : semver.gt(modifiedCurBest, modifiedValue) ? finalBest : value;
                if (curBest < finalBest) {
                    lastBest = curBest;
                }
                return !curBest ? value : semver.gt(modifiedCurBest, modifiedValue) ? curBest : value;
            } else if (curBest && semver.valid(modifiedCurBest)) {
                if (curBest < finalBest) {
                    lastBest = curBest;
                }
                return curBest;
            } else if(finalBest) {
                if (curBest < finalBest) {
                    lastBest = curBest;
                }
                return finalBest;
            }
            return null;
        });

        if (ret) {
            if (lastBest) {
                return [ ret, lastBest ];
            } else {
                return [ ret ];
            }
        } else {
            return null;
        }
};

exports.tagExists = function*(tagName) {
    return !!(yield executil.execHelper(executil.ARGS('git tag --list ' + tagName), true));
}

exports.retrieveCurrentBranchName = function*(allowDetached) {
    var ref;
    try {
        ref = yield executil.execHelper(executil.ARGS('git symbolic-ref HEAD'), true, true);
    } catch (e) {
        if (allowDetached) {
            return null;
        }
        throw new Error('Aborted due to repo ' + process.cwd() + ' not being on a named branch. ' + e.message);
    }
    var match = /refs\/heads\/(.*)/.exec(ref);
    if (!match) {
        throw new Error('Could not parse branch name from: ' + ref);
    }
    return match[1];
}

exports.remoteBranchExists = function*(repo, branch) {
    var branch_token = (repo.remoteName || 'origin') + '/' + branch;
    var stdout = yield executil.execHelper(executil.ARGS('git branch -r --list ' + branch_token), false, false);
    if (stdout.indexOf(branch_token) > -1) {
        return true;
    } else {
        return false;
    }
}

exports.stashAndPop = function*(repo, func) {
    var requiresStash = yield gitutil.pendingChangesExist();
    var branchName = yield gitutil.retrieveCurrentBranchName();

    if (requiresStash) {
        yield executil.execHelper(executil.ARGS('git stash save --all --quiet', 'coho stash'));
    }

    yield func();

    yield gitutil.gitCheckout(branchName);
    if (requiresStash) {
        yield executil.execHelper(executil.ARGS('git stash pop'));
    }
}

exports.pendingChangesExist = function*() {
    return !!(yield executil.execHelper(executil.ARGS('git status --porcelain'), true));
}

exports.gitCheckout = function*(branchName) {
    var curBranch = yield gitutil.retrieveCurrentBranchName(true);
    if (curBranch != branchName) {
        return yield executil.execHelper(executil.ARGS('git checkout -q ', branchName));
    }
}

exports.createNewBranch = function*(branchName) {
    return yield executil.execHelper(executil.ARGS('git branch ', branchName));
}

exports.localBranchExists = function*(name) {
    return !!(yield executil.execHelper(executil.ARGS('git branch --list ' + name), true));
}

exports.retrieveCurrentTagName = function() {
    // This will return the tag name plus commit info it not directly at a tag.
    // That's fine since all users of this function are meant to use the result
    // in an equality check.
    return executil.execHelper(executil.ARGS('git describe --tags HEAD'), true, true);
}

exports.hashForRef = function(ref) {
    return executil.execHelper(executil.ARGS('git rev-parse', ref), true, true);
};

exports.resetFromOrigin = function() {
    return executil.execHelper(executil.ARGS('git reset --hard origin/master'), false, true);
}

exports.gitClean = function() {
    return executil.execHelper(executil.ARGS('git clean -d -f'), false, true);
}

exports.summaryOfChanges = function*(base_sha) {
    var cmd = executil.ARGS('git log --topo-order --no-merges');
    cmd.push(['--pretty=format:* %s']);
    cmd.push(base_sha + '..master');
    return yield executil.execHelper(cmd, true, false);
}

exports.commitChanges = function*(commit_msg) {
    return yield executil.execHelper(executil.ARGS('git commit -am', commit_msg));
}

exports.tagRepo = function*(version) {
    return yield executil.execHelper(executil.ARGS('git tag', version));
}

exports.pushToOrigin = function*(ref) {
    return yield executil.execHelper(executil.ARGS('git push origin', ref));
}

exports.diff = function*(first, second) {
    var args = executil.ARGS('git diff', first + '..' + second);
    return yield executil.execHelper(args, true, false);
}

exports.merge = function*(ref, win, fail) {
    return yield executil.execHelper(executil.ARGS('git merge', ref), false, false, win, fail);
}
