/*
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 request = require('request');
var apputil = require('./apputil');
var flagutil = require('./flagutil');

// Set env variable CORDOVA_GIT_ACCOUNT to <username>:<password> or <api-token> to avoid hitting GitHub rate limits.
var GITHUB_ACCOUNT = process.env.CORDOVA_GIT_ACCOUNT ? process.env.CORDOVA_GIT_ACCOUNT + '@' : '';
var GITHUB_API_URL = 'https://' + GITHUB_ACCOUNT + 'api.github.com/';
var GITHUB_ORGANIZATION = 'apache';
var commentFailed = false;

function addLastCommentInfo (repo, pullRequests, callback) {
    var remaining = pullRequests.length;
    if (remaining === 0) {
        callback();
    }
    pullRequests.forEach(function (pullRequest) {
        var commentsUrl = pullRequest._links.comments && pullRequest._links.comments.href;
        var reviewCommentsUrl = pullRequest._links.review_comments && pullRequest._links.review_comments.href;

        if (commentsUrl && reviewCommentsUrl) {
            // If comments and review_comments URLs are present, use them (more accurate than scraping)
            getPullRequestComments(commentsUrl, function (comments) {
                getPullRequestComments(reviewCommentsUrl, comments, function (comments) {
                    // If we have any comments, grab the user name from the most recent one. If not, we'll display the
                    // owner of the PR (the initial PR comment is not included in the list of comments we get).
                    comments = comments.sort(function (a, b) {
                        // For simplicity, we want to end up with the newest comment first, so reverse sort on create date.
                        return new Date(b.created_at) - new Date(a.created_at);
                    });
                    if (comments.length > 0) {
                        pullRequest.lastUpdatedBy = comments[0] ? comments[0].user.login : pullRequest.user.login;
                    }
                    if (--remaining === 0) {
                        callback();
                    }
                });
            });
        } else {
            // Otherwise, resort to scraping.
            request.get({ url: 'https://github.com/apache/' + repo + '/pull/' + pullRequest.number, headers: { 'User-Agent': 'Cordova Coho' } }, function (err, res, payload) {
                if (err) {
                    if (!commentFailed) {
                        commentFailed = true;
                        console.warn('Pull request scrape request failed: ' + err);
                    }
                } else {
                    var m = /[\s\S]*timeline-comment-header[\s\S]*?"author".*?>(.*?)</.exec(payload);
                    (pullRequest.lastUpdatedBy = m && m[1]) || (''); // eslint-disable-line no-unused-expressions
                }
                if (--remaining === 0) {
                    callback();
                }
            });
        }
    });
}

function getPullRequestComments (url, existingComments, callback) {
    if (GITHUB_ACCOUNT) {
        url = url.replace('https://', 'https://' + GITHUB_ACCOUNT);
    }

    if (typeof existingComments === 'function') {
        callback = existingComments;
        existingComments = [];
    }

    request.get({
        url: url,
        headers: { 'User-Agent': 'Cordova Coho' }
    }, function (err, res, payload) {
        if (err) {
            if (!commentFailed) {
                commentFailed = true;
                console.warn('Getting pull request comments failed: ' + err);
            }
            callback(existingComments);
        }
        var comments = JSON.parse(payload);
        if (!comments.forEach) {
            // We don't have an array, so something failed
            if (!commentFailed) {
                commentFailed = true;
                console.warn('Getting pull request comments failed: did not return an array');
            }
            callback(existingComments);
        }
        callback(existingComments.concat(comments));
    });
}

function listGitHubPullRequests (repo, maxAge, hideUser, short, statsOnly, callback) {
    var url = GITHUB_API_URL + 'repos/' + GITHUB_ORGANIZATION + '/' + repo + '/pulls';

    request.get({ url: url, headers: { 'User-Agent': 'Cordova Coho' } }, function (err, res, pullRequests) {
        if (err) {
            apputil.fatal('Error getting pull requests from GitHub: ' + err);
        } else if (!pullRequests) {
            apputil.fatal('Error: GitHub returned no pull requests');
        } else if (res.headers['x-ratelimit-remaining'] && res.headers['x-ratelimit-remaining'] === 0) {
            var resetEpoch = new Date(res.headers['x-ratelimit-reset'] * 1000);
            var expiration = resetEpoch.getHours() + ':' + resetEpoch.getMinutes() + ':' + resetEpoch.getSeconds();
            apputil.fatal('Error: GitHub rate limit exceeded, wait till ' + expiration + ' before trying again.\n' +
                'See http://developer.github.com/v3/#rate-limiting for details.');
        }

        pullRequests = JSON.parse(pullRequests);
        var origCount = pullRequests.length;

        if (pullRequests.message === 'Bad credentials') {
            apputil.fatal('Error: GitHub Bad credentials. Check your CORDOVA_GIT_ACCOUNT environment variable which should be set with your Github API token: https://github.com/settings/tokens.',
                'CORDOVA_GIT_ACCOUNT used: ' + process.env['CORDOVA_GIT_ACCOUNT']);
        }

        pullRequests = pullRequests.filter(function (p) {
            var updatedDate = new Date(p.updated_at);
            var daysAgo = Math.round((new Date() - updatedDate) / (60 * 60 * 24 * 1000));
            return daysAgo < maxAge;
        });
        var countAfterDateFilter = pullRequests.length;

        if (hideUser) {
            addLastCommentInfo(repo, pullRequests, next);
        } else {
            next();
        }

        function next () {
            var cbObj = {
                'repo': repo,
                'fresh-count': 0,
                'old-count': 0,
                'stale-count': 0,
                'total-count': origCount,
                'message': null
            };

            if (hideUser) {
                pullRequests = pullRequests.filter(function (p) {
                    return p.lastUpdatedBy !== hideUser;
                });
            }
            var count = pullRequests.length;
            cbObj['fresh-count'] = count;

            if (!statsOnly) {
                pullRequests.sort(function (a, b) { return (a.updated_at > b.updated_at) ? -1 : ((b.updated_at > a.updated_at) ? 1 : 0); });
            }

            var countMsg = count + ' Pull Requests';
            if (countAfterDateFilter !== origCount || count !== countAfterDateFilter) {
                countMsg += ' (plus ';
            }
            if (countAfterDateFilter !== origCount) {
                countMsg += (origCount - countAfterDateFilter) + ' old';
                cbObj['old-count'] = (origCount - countAfterDateFilter);
                if (count !== countAfterDateFilter) {
                    countMsg += ', ';
                }
            }
            if (count !== countAfterDateFilter) {
                countMsg += (countAfterDateFilter - count) + ' stale';
                cbObj['stale-count'] = (countAfterDateFilter - count);
            }
            if (countAfterDateFilter !== origCount || count !== countAfterDateFilter) {
                countMsg += ')';
            }

            if (!statsOnly) {
                console.log('\x1B[31m========= ' + repo + ': ' + countMsg + '. =========\x1B[39m');
            }

            if (!statsOnly) {
                pullRequests.forEach(function (pullRequest) {
                    var updatedDate = new Date(pullRequest.updated_at);
                    var daysAgo = Math.round((new Date() - updatedDate) / (60 * 60 * 24 * 1000));
                    console.log('\x1B[33m-----------------------------------------------------------------------------------------------\x1B[39m');
                    console.log('PR #' + pullRequest.number + ': ' + pullRequest.user.login + ': ' +
                        pullRequest.title + ' (\x1B[31m' + (pullRequest.lastUpdatedBy || '<no comments>') + ' ' + daysAgo + ' days ago\x1B[39m)');
                    console.log('\x1B[33m-----------------------------------------------------------------------------------------------\x1B[39m');
                    console.log('* ' + pullRequest.html_url);
                    // console.log('To merge: curl "' + pullRequest.patch_url + '" | git am');
                    if (!pullRequest.head.repo) {
                        console.log('NO REPO EXISTS!');
                    } else {
                        console.log('To merge: coho merge-pr --pr ' + pullRequest.number);
                    }
                    if (pullRequest.body) {
                        if (short && pullRequest.body.length > 100) {
                            console.log(pullRequest.body.substring(0, 100) + '...');
                        } else {
                            console.log(pullRequest.body);
                        }
                    }
                    console.log('');
                });
            }
            cbObj.message = countMsg;
            callback(cbObj);
        }
    });
}

function * listPullRequestsCommand () {
    var opt = flagutil.registerHelpFlag(optimist);
    opt = flagutil.registerRepoFlag(opt)
        .options('max-age', {
            desc: 'Don\'t show pulls older than this (in days)',
            type: 'number',
            default: 1000
        })
        .options('hide-user', {
            desc: 'Hide PRs where the last comment\'s is by this github user.',
            type: 'string'
        })
        .options('stats-only', {
            desc: 'List stats for PRs in the repos specified.',
            type: 'bool'
        })
        .options('sort-ascending', {
            desc: 'Used in conjunction with --stats-only. Sort the PRs ascending.',
            type: 'bool'
        })
        .options('json', {
            desc: 'Used in conjunction with --stats-only. Output the report in JSON format.',
            type: 'bool'
        })
        .options('short', {
            desc: 'Truncates PR body description',
            type: 'bool'
        });
    opt.usage('Reports what GitHub pull requests are open for the given repositories.\n' +
               '\n' +
               'Example usage: $0 list-pulls --hide-user="agrieve" | tee pulls.list | less -R\n' +
               'Example usage: $0 list-pulls --max-age=365 --repo=.\n' +
               'Example usage: $0 list-pulls --max-age=365 --repo=. --stats-only --json --sort-ascending --hide-user=cordova-qa | tail -n +2\n' +
               '\n' +
               'Please note that GitHub rate limiting applies. See http://developer.github.com/v3/#rate-limiting for details.\n' +
               'You can also set the CORDOVA_GIT_ACCOUNT environment variable with your Github API key: https://github.com/settings/tokens\n'
    );
    var argv = opt.argv;

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

    var repos = flagutil.computeReposFromFlag(argv.r);
    var report = {
        'title': 'coho list-pulls report',
        // "command" : process.argv,
        'timestamp': new Date().toJSON(),
        'max-age': argv['max-age'],
        'repos': []
    };
    var simple_report = [];

    function next (reportObject) {
        if (reportObject && argv['stats-only']) {
            if (argv.json) {
                report.repos.push(reportObject);
            } else {
                simple_report.push(reportObject);
            }
        }

        if (repos.length) {
            var repo = repos.shift();
            listGitHubPullRequests(repo.repoName, argv['max-age'], argv['hide-user'], argv.short, argv['stats-only'], next);
        } else if (argv['stats-only']) { // done
            function compareFunc (a, b) { // eslint-disable-line no-inner-declarations
                if (a['fresh-count'] < b['fresh-count']) {
                    return argv['sort-ascending'] ? -1 : 1;
                }
                if (a['fresh-count'] > b['fresh-count']) {
                    return argv['sort-ascending'] ? 1 : -1;
                }
                return 0;
            }

            if (argv.json) {
                report.repos.sort(compareFunc);
                console.log(JSON.stringify(report, null, 4));
            } else {
                simple_report.sort(compareFunc);
                simple_report.forEach(function (report) {
                    console.log(report.repo + ' --> ' + report.message);
                });
            }
        }
    }

    var url = 'https://github.com/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr';
    repos.forEach(function (repo) {
        url += '+repo%3Aapache%2F' + repo.repoName;
    });
    if (!(argv['stats-only'] && argv['json'])) {
        console.log(url);
    }
    next();
}

module.exports = listPullRequestsCommand;
