/*
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 optimist = require('optimist');
var apputil = require('./apputil');
var executil = require('./executil');
var flagutil = require('./flagutil');
var gitutil = require('./gitutil');
var repoutil = require('./repoutil');
var print = apputil.print;

module.exports = function * (_argv) {
    var opt = flagutil.registerRepoFlag(optimist);
    opt = flagutil.registerDepthFlag(opt);
    opt = opt
        .options('b', {
            alias: 'branch',
            desc: 'The name of the branch to update. Can be specified multiple times to update multiple branches.',
            default: ['master']
        })
        .options('fetch', {
            type: 'boolean',
            desc: 'Use --no-fetch to skip the "git fetch" step.',
            default: true
        });
    opt = flagutil.registerHelpFlag(opt);
    var argv = opt
        .usage('Updates git repositories by performing the following commands:\n' +
               '    save active branch\n' +
               '    git fetch $REMOTE \n' +
               '    git stash\n' +
               '    for each specified branch:\n' +
               '        git checkout $BRANCH\n' +
               '        git rebase $REMOTE/$BRANCH\n' +
               '        git checkout -\n' +
               '    git checkout $SAVED_ACTIVE_BRANCH\n' +
               '    git stash pop\n' +
               '\n' +
               'Usage: $0 repo-update [--depth 10] [-b branch] [--no-fetch] [-r repos]')
        .argv;

    if (argv.h) {
        optimist.showHelp();
        process.exit(1);
    }

    var depth = argv.depth ? argv.depth : null;

    var branches = Array.isArray(argv.b) ? argv.b : [argv.b];
    var repos = flagutil.computeReposFromFlag(argv.r, true);
    apputil.prefixLength = Math.max.apply(null,
        [apputil.prefixLength].concat(
            repos.map(function (r) { return r.repoName.length + 2; }))
    );

    // ensure that any missing repos are cloned
    yield require('./repo-clone').cloneRepos(repos, true, depth);
    yield updateRepos(repos, branches, !argv.fetch);
};

function * updateRepos (repos, branches, noFetch) {
    // Pre-fetch checks.
    yield repoutil.forEachRepo(repos, function * (repo) {
        if (repo.svn) {
            return;
        }
        // Ensure it's on a named branch.
        yield gitutil.retrieveCurrentBranchName();
        // Find the apache remote.
        if (!repo.remoteName) {
            repo.remoteName = yield determineApacheRemote(repo);
        }
    });

    if (!noFetch) {
        var fetchPromises = [];
        yield repoutil.forEachRepo(repos, function * (repo) {
            if (repo.svn) {
                return;
            }
            // Note: this does the same as git fetch --tags origin && git fetch origin
            fetchPromises.push(executil.execHelper(executil.ARGS('git remote update ', repo.remoteName), 3));
        });
        if (fetchPromises.length > 1) {
            print('Waiting for concurrent fetches to finish...');
        }
        yield fetchPromises;
    }

    if (branches && branches.length) {
        var errors = '';
        yield repoutil.forEachRepo(repos, function * (repo) {
            if (repo.id === 'firefoxos' && process.platform === 'win32') {
                console.log('Skipping firefox OS repo on Windows as it fails due to max path length issues');
                return;
            }

            if (repo.svn) {
                try {
                    yield executil.execHelper(executil.ARGS('svn up'), /* silent */ false, /* allowError */ true);
                } catch (e) {
                    errors += '(' + repo.repoName + '): ' + e + '\n';
                    // Log failure and continue updating other repos
                    console.log(e);
                }
                return;
            }
            var staleBranches = {};
            for (var i = 0; i < branches.length; ++i) {
                var branchName = branches[i];
                if (yield gitutil.localBranchExists(branchName)) {
                    if (yield gitutil.remoteBranchExists(repo, branchName)) {
                        var changes = yield executil.execHelper(executil.ARGS('git log --oneline ' + branchName + '..' + repo.remoteName + '/' + branchName),
                            /* silent */ true, /* allowError */ true);
                        staleBranches[branchName] = !!changes;
                    }
                } else {
                    yield executil.execHelper(executil.ARGS('git checkout -b ' + branchName + ' remotes/' + repo.remoteName + '/' + branchName),
                        /* silent */ true, /* allowError */ false);
                }
            }
            staleBranches = branches.filter(function (branchName) {
                return !!staleBranches[branchName];
            });
            if (!staleBranches.length) {
                print('Already up-to-date: ' + repo.repoName);
            } else {
                yield gitutil.stashAndPop(repo, function * () {
                    for (var i = 0; i < staleBranches.length; ++i) {
                        var branchName = staleBranches[i];
                        yield gitutil.gitCheckout(branchName);
                        try {
                            var ret = yield executil.execHelper(executil.ARGS('git merge --ff-only', repo.remoteName + '/' + branchName),
                                /* silent */ false, /* allowError */ true);
                            if (ret === null) {
                                try {
                                    ret = yield executil.execHelper(executil.ARGS('git rebase ' + repo.remoteName + '/' + branchName),
                                        /* silent */ false, /* allowError */ true);
                                } catch (ret) {
                                    apputil.fatal('\n\nUpdate failed. Run again with --no-fetch to try again without re-fetching.');
                                }
                            }
                        } catch (e) {
                            errors += '(' + repo.repoName + '): ' + e + '\n';
                            // Log failure and continue updating other repos
                            console.log(e);
                        }
                    }
                });
            }
        });
        if (errors) {
            console.log('ERRORS:');
            console.log(errors);
        }
    }
}
module.exports.updateRepos = updateRepos;

function * determineApacheRemote (repo) {
    var fields = (yield executil.execHelper(executil.ARGS('git remote -v'), true)).split(/\s+/);

    var ret = null;

    // prefer github - in particular, ASF remote does not respond well to repo-update command.
    [
        'git@github.com:apache/',
        'github.com/apache/',
        'git-wip-us.apache.org/repos/asf/',
        'git.apache.org/'
    ].forEach(function (validRepo) {
        for (var i = 1; i < fields.length; i += 3) {
            if (!ret && fields[i].indexOf(validRepo + repo.repoName) !== -1) {
                ret = fields[i - 1];
            }
        }
    });

    if (ret) {
        return ret;
    }
    apputil.fatal('Could not find an apache remote for repo ' + repo.repoName);
}
