/*
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 flagutil = require('./flagutil');
var optimist = require('optimist');
var executil = require('./executil');
var gitutil = require('./gitutil');
var repoutil = require('./repoutil');
var REMOTE = 'https://github.com/apache/';
var apputil = require('./apputil');
var url = require('url');
var opener = require('opener');

module.exports = function * (argv) {
    var opt = flagutil.registerHelpFlag(optimist);
    opt.options('branch', {
        desc: 'Topic branch for which to create pull request (Default: current branch) ',
        demand: false
    });
    argv = opt
        .usage('Launch github URL to create PR\n' +
        '\n' +
        'Usage: $0 create-pr --branch <topic_branch>')
        .argv;
    if (argv.h) {
        optimist.showHelp();
        process.exit(1);
    }
    var currentRepo = repoutil.getRepoById(repoutil.resolveCwdRepo());
    var currentBranch = opt.branch;
    if (!currentBranch) {
        currentBranch = yield gitutil.retrieveCurrentBranchName();
    }
    if (currentBranch === 'master') {
        console.log('You can crate a PR only for a topic branch that is not master. Use --branch to specify the topic branch or checkout to the topic branch.');
    }
    var remoteInfo = yield getRemoteName(currentBranch);
    var remoteFork = yield getRemoteForkName(remoteInfo.remoteName);
    var url = REMOTE + currentRepo.repoName + '/compare/master...' + remoteFork + ':' + remoteInfo.remoteBranch + '?expand=1';
    console.log('Navigating to: ' + url);
    opener(url);
};

function * getRemoteForkName (remoteName) {
    var remotes = (yield executil.execHelper(executil.ARGS('git remote -v'), /* silent */ true)).split('\n');
    var remoteUrl;
    for (var i = 0; i < remotes.length; i++) {
        // fork    https://github.com/forkName/cordova-coho.git (push)
        var tokens = remotes[i].split(/\s+/);
        if (tokens[2] === '(push)' && tokens[0] === remoteName) {
            remoteUrl = tokens[1];
            break;
        }
    }
    if (!remoteUrl) {
        apputil.fatal('Cannot find remote Url: ' + remotes);
    }
    var parsed = url.parse(remoteUrl);
    // parsed => /forkName/cordova-coho.git
    var forkName = (parsed.pathname.split('/'))[1];
    return forkName;
}

function * getRemoteName (currentBranch) {
    var branches = (yield executil.execHelper(executil.ARGS('git branch -vv'), /* silent */ true)).split('\n');
    //* create-pr           3bed9b5 [remotes/fork/create-pr] Add support for launching URL to create a PR
    for (var i = 0; i < branches.length; i++) {
        //* create-pr           3bed9b5 [remotes/fork/create-pr] Add support for launching URL to create a PR
        // 0   1                    2       3
        var tokens = branches[i].split(/\s+/);
        if (tokens[0] === '*') {
            // found the current branch
            if (currentBranch !== tokens[1]) {
                apputil.fatal('Unexpected format. Cannot find remote branch: ' + tokens[1] + '!== ' + currentBranch);
            }
            // if there is no upstream remote specified - we have no choice but to bail
            var remote = tokens[3];
            if (remote.indexOf('[') !== 0) {
                apputil.fatal('Cannot determine upstream remote branch. Have you already pushed it? \n' +
                    'To push and set upstream: git push -u <remoteFork> ' + currentBranch + '\n' +
                    'To set upstream branch:   git branch --set-upstream <remoteFork>');
            }
            // Strip off the []
            remote = remote.substring(1, remote.length - 1);
            tokens = remote.split('/');
            var remoteName = tokens[0];
            var remoteBranch = tokens[1];
            if (remoteName === 'remotes') {
                remoteName = tokens[1];
                remoteBranch = tokens[2];
            }
            return { remoteName: remoteName, remoteBranch: remoteBranch };
        }
    }
    apputil.fatal('Unexpected error. Cannot determine remote: ' + branches);
}
