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

"""Query issues in a release branch

This script searches for issues referenced via pull-requests in a release
branch in order to simplify tracking changes such as automated backports,
manual backports, security fixes, and stability fixes.

A formatted report is printed to standard output either in JSON or
reStructuredText.

Since an issue is required for all changes to release branches, merged PRs
must have at least one instance of the phrase "Fixes #1234" in the body. This
script will throw an error if a PR has been made without an associated issue.

Usage:
    ./scripts/release/list_backports.py \
        -t ~/.ghtoken \
        -b v2.7-branch \
        -s 2021-12-15 -e 2022-04-22 \
        -P 45074 -P 45868 -P 44918 -P 41234 -P 41174 \
        -j | jq . | tee /tmp/backports.json

    GITHUB_TOKEN="<secret>" \
    ./scripts/release/list_backports.py \
        -b v3.0-branch \
        -p 43381 \
        -j | jq . | tee /tmp/backports.json
"""

import argparse
from datetime import datetime, timedelta
import io
import json
import logging
import os
import re
import sys

# Requires PyGithub
from github import Github


# 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 parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--token', dest='tokenfile',
                        help='File containing GitHub token (alternatively, use GITHUB_TOKEN env variable)', metavar='FILE')
    parser.add_argument('-b', '--base', dest='base',
                        help='branch (base) for PRs (e.g. v2.7-branch)', metavar='BRANCH', required=True)
    parser.add_argument('-j', '--json', dest='json', action='store_true',
                        help='print output in JSON rather than RST')
    parser.add_argument('-s', '--start', dest='start', help='start date (YYYY-mm-dd)',
                        metavar='START_DATE', type=valid_date_type)
    parser.add_argument('-e', '--end', dest='end', help='end date (YYYY-mm-dd)',
                        metavar='END_DATE', type=valid_date_type)
    parser.add_argument("-o", "--org", default="zephyrproject-rtos",
                        help="Github organisation")
    parser.add_argument('-p', '--include-pull', dest='includes',
                        help='include pull request (can be specified multiple times)',
                        metavar='PR', type=int, action='append', default=[])
    parser.add_argument('-P', '--exclude-pull', dest='excludes',
                        help='exlude pull request (can be specified multiple times, helpful for version bumps and release notes)',
                        metavar='PR', type=int, action='append', default=[])
    parser.add_argument("-r", "--repo", default="zephyr",
                        help="Github repository")

    args = parser.parse_args()

    if args.includes:
        if getattr(args, 'start'):
            logging.error(
                'the --start argument should not be used with --include-pull')
            return None
        if getattr(args, 'end'):
            logging.error(
                'the --end argument should not be used with --include-pull')
            return None
    else:
        if not getattr(args, 'start'):
            logging.error(
                'if --include-pr PR is not used, --start START_DATE is required')
            return None

        if not getattr(args, 'end'):
            setattr(args, 'end', datetime.now())

        if args.end < args.start:
            logging.error(
                f'end date {args.end} is before start date {args.start}')
            return None

    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 Backport(object):
    def __init__(self, repo, base, pulls):
        self._base = base
        self._repo = repo
        self._issues = []
        self._pulls = pulls

        self._pulls_without_an_issue = []
        self._pulls_with_invalid_issues = {}

    @staticmethod
    def by_date_range(repo, base, start_date, end_date, excludes):
        """Create a Backport object with the provided repo,
        base, start datetime object, and end datetime objects, and
        list of excluded PRs"""

        pulls = []

        unfiltered_pulls = repo.get_pulls(
            base=base, state='closed')
        for p in unfiltered_pulls:
            if not p.merged:
                # only consider merged backports
                continue

            if p.closed_at < start_date or p.closed_at >= end_date + timedelta(1):
                # only concerned with PRs within time window
                continue

            if p.number in excludes:
                # skip PRs that have been explicitly excluded
                continue

            pulls.append(p)

        # paginated_list.sort() does not exist
        pulls = sorted(pulls, key=lambda x: x.number)

        return Backport(repo, base, pulls)

    @staticmethod
    def by_included_prs(repo, base, includes):
        """Create a Backport object with the provided repo,
        base, and list of included PRs"""

        pulls = []

        for i in includes:
            try:
                p = repo.get_pull(i)
            except Exception:
                p = None

            if not p:
                logging.error(f'{i} is not a valid pull request')
                return None

            if p.base.ref != base:
                logging.error(
                    f'{i} is not a valid pull request for base {base} ({p.base.label})')
                return None

            pulls.append(p)

        # paginated_list.sort() does not exist
        pulls = sorted(pulls, key=lambda x: x.number)

        return Backport(repo, base, pulls)

    @staticmethod
    def sanitize_title(title):
        # TODO: sanitize titles such that they are suitable for both JSON and ReStructured Text
        # could also automatically fix titles like "Automated backport of PR #1234"
        return title

    def print(self):
        for i in self.get_issues():
            title = Backport.sanitize_title(i.title)
            # * :github:`38972` - logging: Cleaning references to tracing in logging
            print(f'* :github:`{i.number}` - {title}')

    def print_json(self):
        issue_objects = []
        for i in self.get_issues():
            obj = {}
            obj['id'] = i.number
            obj['title'] = Backport.sanitize_title(i.title)
            obj['url'] = f'https://github.com/{self._repo.organization.login}/{self._repo.name}/pull/{i.number}'
            issue_objects.append(obj)

        print(json.dumps(issue_objects))

    def get_pulls(self):
        return self._pulls

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

        issue_map = {}
        self._pulls_without_an_issue = []
        self._pulls_with_invalid_issues = {}

        for p in self._pulls:
            # check for issues in this pr
            issues_for_this_pr = {}
            with io.StringIO(p.body) as buf:
                for line in buf.readlines():
                    line = line.strip()
                    match = re.search(r"^Fixes[:]?\s*#([1-9][0-9]*).*", line)
                    if not match:
                        match = re.search(
                            rf"^Fixes[:]?\s*https://github\.com/{self._repo.organization.login}/{self._repo.name}/issues/([1-9][0-9]*).*", line)
                    if not match:
                        continue
                    issue_number = int(match[1])
                    issue = self._repo.get_issue(issue_number)
                    if not issue:
                        if not self._pulls_with_invalid_issues[p.number]:
                            self._pulls_with_invalid_issues[p.number] = [
                                issue_number]
                        else:
                            self._pulls_with_invalid_issues[p.number].append(
                                issue_number)
                        logging.error(
                            f'https://github.com/{self._repo.organization.login}/{self._repo.name}/pull/{p.number} references invalid issue number {issue_number}')
                        continue
                    issues_for_this_pr[issue_number] = issue

            # report prs missing issues later
            if len(issues_for_this_pr) == 0:
                logging.error(
                    f'https://github.com/{self._repo.organization.login}/{self._repo.name}/pull/{p.number} does not have an associated issue')
                self._pulls_without_an_issue.append(p)
                continue

            # FIXME: when we have upgrade to python3.9+, use "issue_map | issues_for_this_pr"
            issue_map = {**issue_map, **issues_for_this_pr}

        issues = list(issue_map.values())

        # paginated_list.sort() does not exist
        issues = sorted(issues, key=lambda x: x.number)

        self._issues = issues

        return self._issues

    def get_pulls_without_issues(self):
        if self._pulls_without_an_issue:
            return self._pulls_without_an_issue

        self.get_issues()

        return self._pulls_without_an_issue

    def get_pulls_with_invalid_issues(self):
        if self._pulls_with_invalid_issues:
            return self._pulls_with_invalid_issues

        self.get_issues()

        return self._pulls_with_invalid_issues


def main():
    args = parse_args()

    if not args:
        return os.EX_DATAERR

    try:
        gh = Github(args.token)
    except Exception:
        logging.error('failed to authenticate with GitHub')
        return os.EX_DATAERR

    try:
        repo = gh.get_repo(args.org + '/' + args.repo)
    except Exception:
        logging.error('failed to obtain Github repository')
        return os.EX_DATAERR

    bp = None
    if args.includes:
        bp = Backport.by_included_prs(repo, args.base, set(args.includes))
    else:
        bp = Backport.by_date_range(repo, args.base,
                                    args.start, args.end, set(args.excludes))

    if not bp:
        return os.EX_DATAERR

    pulls_with_invalid_issues = bp.get_pulls_with_invalid_issues()
    if pulls_with_invalid_issues:
        logging.error('The following PRs link to invalid issues:')
        for (p, lst) in pulls_with_invalid_issues:
            logging.error(
                f'\nhttps://github.com/{repo.organization.login}/{repo.name}/pull/{p.number}: {lst}')
        return os.EX_DATAERR

    pulls_without_issues = bp.get_pulls_without_issues()
    if pulls_without_issues:
        logging.error(
            'Please ensure the body of each PR to a release branch contains "Fixes #1234"')
        logging.error('The following PRs are lacking associated issues:')
        for p in pulls_without_issues:
            logging.error(
                f'https://github.com/{repo.organization.login}/{repo.name}/pull/{p.number}')
        return os.EX_DATAERR

    if args.json:
        bp.print_json()
    else:
        bp.print()

    return os.EX_OK


if __name__ == '__main__':
    sys.exit(main())
