#!/usr/bin/env python3
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

# Lists all closes issues since a given date

import argparse
import sys
import os
import re
import time
import threading
import requests


args = None


class Spinner:
    busy = False
    delay = 0.1

    @staticmethod
    def spinning_cursor():
        while 1:
            for cursor in '|/-\\':
                yield cursor

    def __init__(self, delay=None):
        self.spinner_generator = self.spinning_cursor()
        if delay and float(delay):
            self.delay = delay

    def spinner_task(self):
        while self.busy:
            sys.stdout.write(next(self.spinner_generator))
            sys.stdout.flush()
            time.sleep(self.delay)
            sys.stdout.write('\b')
            sys.stdout.flush()

    def __enter__(self):
        self.busy = True
        threading.Thread(target=self.spinner_task).start()

    def __exit__(self, exception, value, tb):
        self.busy = False
        time.sleep(self.delay)
        if exception is not None:
            return False


class Issues:
    def __init__(self, org, repo, token):
        self.repo = repo
        self.org = org
        self.issues_url = "https://github.com/%s/%s/issues" % (
            self.org, self.repo)
        self.github_url = 'https://api.github.com/repos/%s/%s' % (
            self.org, self.repo)

        self.api_token = token
        self.headers = {}
        self.headers['Authorization'] = 'token %s' % self.api_token
        self.headers['Accept'] = 'application/vnd.github.golden-comet-preview+json'
        self.items = []

    def get_pull(self, pull_nr):
        url = ("%s/pulls/%s" % (self.github_url, pull_nr))
        response = requests.get("%s" % (url), headers=self.headers)
        if response.status_code != 200:
            raise RuntimeError(
                "Failed to get issue due to unexpected HTTP status code: {}".format(
                    response.status_code)
            )
        item = response.json()
        return item

    def get_issue(self, issue_nr):
        url = ("%s/issues/%s" % (self.github_url, issue_nr))
        response = requests.get("%s" % (url), headers=self.headers)
        if response.status_code != 200:
            return None

        item = response.json()
        return item

    def list_issues(self, url):
        response = requests.get("%s" % (url), headers=self.headers)
        if response.status_code != 200:
            raise RuntimeError(
                "Failed to get issue due to unexpected HTTP status code: {}".format(
                    response.status_code)
            )
        self.items = self.items + response.json()

        try:
            print("Getting more items...")
            next_issues = response.links["next"]
            if next_issues:
                next_url = next_issues['url']
                self.list_issues(next_url)
        except KeyError:
            pass

    def issues_since(self, date, state="closed"):
        self.list_issues("%s/issues?per_page=100&state=%s&since=%s" %
                         (self.github_url, state, date))

    def pull_requests(self, base='v1.14-branch', state='closed'):
        self.list_issues("%s/pulls?per_page=100&state=%s&base=%s" %
                         (self.github_url, state, base))


def parse_args():
    global args

    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument("-o", "--org", default="zephyrproject-rtos",
                        help="Github organisation")

    parser.add_argument("-r", "--repo", default="zephyr",
                        help="Github repository")

    parser.add_argument("-f", "--file", required=True,
                        help="Name of output file.")

    parser.add_argument("-s", "--issues-since",
                        help="""List issues since date where date
        is in the format 2019-09-01.""")

    parser.add_argument("-b", "--issues-in-pulls",
                        help="List issues in pulls for a given branch")

    parser.add_argument("-c", "--commits-file",
                        help="""File with all commits (git log a..b) to
        be parsed for fixed bugs.""")

    args = parser.parse_args()


def main():
    parse_args()

    token = os.environ.get('GITHUB_TOKEN', None)
    if not token:
        sys.exit("""Github token not set in environment,
set the env. variable GITHUB_TOKEN please and retry.""")

    i = Issues(args.org, args.repo, token)

    if args.issues_since:
        i.issues_since(args.issues_since)
        count = 0
        with open(args.file, "w") as f:
            for issue in i.items:
                if 'pull_request' not in issue:
                    # * :github:`8193` - STM32 config BUILD_OUTPUT_HEX fail
                    f.write("* :github:`{}` - {}\n".format(
                        issue['number'], issue['title'].strip()))
                    count = count + 1
    elif args.issues_in_pulls:
        i.pull_requests(base=args.issues_in_pulls)
        count = 0

        bugs = set()
        backports = []
        for issue in i.items:
            if not isinstance(issue['body'], str):
                continue
            match = re.findall(r"(Fixes|Closes|Fixed|close):? #([0-9]+)",
                               issue['body'], re.MULTILINE)
            if match:
                for mm in match:
                    bugs.add(mm[1])
            else:
                match = re.findall(
                    r"Backport #([0-9]+)", issue['body'], re.MULTILINE)
                if match:
                    backports.append(match[0])

        # follow PRs to their origin (backports)
        with Spinner():
            for p in backports:
                item = i.get_pull(p)
                match = re.findall(r"(Fixes|Closes|Fixed|close):? #([0-9]+)",
                                   item['body'], re.MULTILINE)
                for mm in match:
                    bugs.add(mm[1])

        # now open commits
        if args.commits_file:
            print("Open commits file and parse for fixed bugs...")
            with open(args.commits_file, "r") as commits:
                content = commits.read()
                match = re.findall(r"(Fixes|Closes|Fixed|close):? #([0-9]+)",
                                   str(content), re.MULTILINE)
                for mm in match:
                    bugs.add(mm[1])

        print("Create output file...")
        with Spinner():
            with open(args.file, "w") as f:
                for m in sorted(bugs):
                    item = i.get_issue(m)
                    if item:
                        # * :github:`8193` - STM32 config BUILD_OUTPUT_HEX fail
                        f.write("* :github:`{}` - {}\n".format(
                                item['number'], item['title'].strip()))


if __name__ == '__main__':
    main()
