#!/usr/bin/env python3
# Copyright (c) 2021, Facebook
#
# SPDX-License-Identifier: Apache-2.0

"""Query the Top-Ten Bug Bashers

This script will query the top-ten Bug Bashers in a specified date window.

Usage:
    ./scripts/bug-bash.py -t ~/.ghtoken -b 2021-07-26 -e 2021-08-07
    GITHUB_TOKEN="..." ./scripts/bug-bash.py -b 2021-07-26 -e 2021-08-07
"""

import argparse
from datetime import datetime, timedelta
import operator
import os

# Requires PyGithub
from github import Github


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-a', '--all', dest='all',
                        help='Show all bugs squashed', action='store_true')
    parser.add_argument('-t', '--token', dest='tokenfile',
                        help='File containing GitHub token (alternatively, use GITHUB_TOKEN env variable)', metavar='FILE')
    parser.add_argument('-s', '--start', dest='start', help='start date (YYYY-mm-dd)',
                        metavar='START_DATE', type=valid_date_type, required=True)
    parser.add_argument('-e', '--end', dest='end', help='end date (YYYY-mm-dd)',
                        metavar='END_DATE', type=valid_date_type, required=True)

    args = parser.parse_args()

    if args.end < args.start:
        raise ValueError(
            'end date {} is before start date {}'.format(args.end, args.start))

    if args.tokenfile:
        with open(args.tokenfile, 'r') as file:
            token = file.read()
            token = token.strip()
    else:
        if 'GITHUB_TOKEN' not in os.environ:
            raise ValueError('No credentials specified')
        token = os.environ['GITHUB_TOKEN']

    setattr(args, 'token', token)

    return args


class BugBashTally(object):
    def __init__(self, gh, start_date, end_date):
        """Create a BugBashTally object with the provided Github object,
        start datetime object, and end datetime object"""
        self._gh = gh
        self._repo = gh.get_repo('zephyrproject-rtos/zephyr')
        self._start_date = start_date
        self._end_date = end_date

        self._issues = []
        self._pulls = []

    def get_tally(self):
        """Return a dict with (key = user, value = score)"""
        tally = dict()
        for p in self.get_pulls():
            user = p.user.login
            tally[user] = tally.get(user, 0) + 1

        return tally

    def get_rev_tally(self):
        """Return a dict with (key = score, value = list<user>) sorted in
        descending order"""
        # there may be ties!
        rev_tally = dict()
        for user, score in self.get_tally().items():
            if score not in rev_tally:
                rev_tally[score] = [user]
            else:
                rev_tally[score].append(user)

        # sort in descending order by score
        rev_tally = dict(
            sorted(rev_tally.items(), key=operator.itemgetter(0), reverse=True))

        return rev_tally

    def get_top_ten(self):
        """Return a dict with (key = score, value = user) sorted in
        descending order"""
        top_ten = []
        for score, users in self.get_rev_tally().items():
            # do not sort users by login - hopefully fair-ish
            for user in users:
                if len(top_ten) == 10:
                    return top_ten

                top_ten.append(tuple([score, user]))

        return top_ten

    def get_pulls(self):
        """Return GitHub pull requests that squash bugs in the provided
        date window"""
        if self._pulls:
            return self._pulls

        self.get_issues()

        return self._pulls

    def get_issues(self):
        """Return GitHub issues representing bugs in the provided date
        window"""
        if self._issues:
            return self._issues

        cutoff = self._end_date + timedelta(1)
        issues = self._repo.get_issues(state='closed', labels=[
            'bug'], since=self._start_date)

        for i in issues:
            # the PyGithub API and v3 REST API do not facilitate 'until'
            # or 'end date' :-/
            if i.closed_at < self._start_date or i.closed_at > cutoff:
                continue

            ipr = i.pull_request
            if ipr is None:
                # ignore issues without a linked pull request
                continue

            prid = int(ipr.html_url.split('/')[-1])
            pr = self._repo.get_pull(prid)
            if not pr.merged:
                # pull requests that were not merged do not count
                continue

            self._pulls.append(pr)
            self._issues.append(i)

        return self._issues


# https://gist.github.com/monkut/e60eea811ef085a6540f
def valid_date_type(arg_date_str):
    """custom argparse *date* type for user dates values given from the
    command line"""
    try:
        return datetime.strptime(arg_date_str, "%Y-%m-%d")
    except ValueError:
        msg = "Given Date ({0}) not valid! Expected format, YYYY-MM-DD!".format(arg_date_str)
        raise argparse.ArgumentTypeError(msg)


def print_top_ten(top_ten):
    """Print the top-ten bug bashers"""
    for score, user in top_ten:
        # print tab-separated value, to allow for ./script ... > foo.csv
        print('{}\t{}'.format(score, user))


def main():
    args = parse_args()
    bbt = BugBashTally(Github(args.token), args.start, args.end)
    if args.all:
        # print one issue per line
        issues = bbt.get_issues()
        pulls = bbt.get_pulls()
        n = len(issues)
        m = len(pulls)
        assert n == m
        for i in range(0, n):
            print('{}\t{}\t{}'.format(
                issues[i].number, pulls[i].user.login, pulls[i].title))
    else:
        # print the top ten
        print_top_ten(bbt.get_top_ten())


if __name__ == '__main__':
    main()
