#!/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?state=%s&since=%s" %
                         (self.github_url, state, date))

    def pull_requests(self, base='v1.14-branch', state='closed'):
        self.list_issues("%s/pulls?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('GH_TOKEN', None)
    if not token:
        sys.exit("""Github token not set in environment,
set the env. variable GH_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']))
                    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']))

if __name__ == '__main__':
    main()
