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

// 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] || '';
                }
                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) {
                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;
