#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 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.

"""
Simple script that queries GitHub for all open PRs, then finds the ones without
issue number in title, and the ones where the linked JIRA is already closed
"""

import os
import sys
sys.path.append(os.path.dirname(__file__))
import argparse
import json
import re
from github import Github
from jira import JIRA
from datetime import datetime
from time import strftime
try:
  from jinja2 import Environment, BaseLoader
  can_do_html = True
except:
  can_do_html = False

def read_config():
  parser = argparse.ArgumentParser(description='Find open Pull Requests that need attention')
  parser.add_argument('--json', action='store_true', default=False, help='Output as json')
  parser.add_argument('--html', action='store_true', default=False, help='Output as html')
  parser.add_argument('--token', help='Github access token in case you query too often anonymously')
  newconf = parser.parse_args()
  return newconf


def out(text):
  global conf
  if not (conf.json or conf.html):
    print(text)

def make_html(dict):
  if not can_do_html:
    print ("ERROR: Cannot generate HTML. Please install jinja2")
    sys.exit(1)
  global conf
  template = Environment(loader=BaseLoader).from_string("""
  <h1>Lucene Github PR report</h1>

  <p>Number of open Pull Requests: {{ open_count }}</p>

  <h2>PRs lacking JIRA reference in title ({{ no_jira_count }})</h2>
  <ul>
  {% for pr in no_jira %}
    <li><a href="https://github.com/apache/lucene/pull/{{ pr.number }}">#{{ pr.number }}: {{ pr.created }} {{ pr.title }}</a> ({{ pr.user }})</li>
  {%- endfor %}
  </ul>

  <h2>Open PRs with a resolved JIRA ({{ closed_jira_count }})</h2>
  <ul>
  {% for pr in closed_jira %}
    <li><a href="https://github.com/apache/lucene/pull/{{ pr.pr_number }}">#{{ pr.pr_number }}</a>: <a href="https://issues.apache.org/jira/browse/{{ pr.issue_key }}">{{ pr.status }} {{ pr.resolution_date }} {{ pr.issue_key}}: {{ pr.issue_summary }}</a> ({{ pr.assignee }})</li>
  {%- endfor %}
  </ul>
  """)
  return template.render(dict)

def main():
  global conf
  conf = read_config()
  token = conf.token if conf.token is not None else None
  if token:
    gh = Github(token)
  else:
    gh = Github()
  jira = JIRA('https://issues.apache.org/jira')
  result = {}
  repo = gh.get_repo('apache/lucene')
  open_prs = repo.get_pulls(state='open')
  out("Lucene Github PR report")
  out("============================")
  out("Number of open Pull Requests: %s" % open_prs.totalCount)
  result['open_count'] = open_prs.totalCount

  lack_jira = list(filter(lambda x: not re.match(r'.*\b(LUCENE)-\d{3,6}\b', x.title), open_prs))
  result['no_jira_count'] = len(lack_jira)
  lack_jira_list = []
  for pr in lack_jira:
    lack_jira_list.append({'title': pr.title, 'number': pr.number, 'user': pr.user.login, 'created': pr.created_at.strftime("%Y-%m-%d")})
  result['no_jira'] = lack_jira_list
  out("\nPRs lacking JIRA reference in title")
  for pr in lack_jira_list:
    out("  #%s: %s %s (%s)" % (pr['number'], pr['created'], pr['title'], pr['user'] ))

  out("\nOpen PRs with a resolved JIRA")
  has_jira = list(filter(lambda x: re.match(r'.*\b(LUCENE)-\d{3,6}\b', x.title), open_prs))

  issue_ids = []
  issue_to_pr = {}
  for pr in has_jira:
    jira_issue_str = re.match(r'.*\b((LUCENE)-\d{3,6})\b', pr.title).group(1)
    issue_ids.append(jira_issue_str)
    issue_to_pr[jira_issue_str] = pr

  resolved_jiras = jira.search_issues(jql_str="key in (%s) AND status in ('Closed', 'Resolved')" % ", ".join(issue_ids))
  closed_jiras = []
  for issue in resolved_jiras:
    pr_title = issue_to_pr[issue.key].title
    pr_number = issue_to_pr[issue.key].number
    assignee = issue.fields.assignee.name if issue.fields.assignee else None
    closed_jiras.append({ 'issue_key': issue.key,
                           'status': issue.fields.status.name,
                           'resolution': issue.fields.resolution.name,
                           'resolution_date': issue.fields.resolutiondate[:10],
                           'pr_number': pr_number,
                           'pr_title': pr_title,
                           'issue_summary': issue.fields.summary,
                           'assignee': assignee})

  closed_jiras.sort(key=lambda r: r['pr_number'], reverse=True)
  for issue in closed_jiras:
    out("  #%s: %s %s %s: %s (%s)" % (issue['pr_number'],
                                  issue['status'],
                                  issue['resolution_date'],
                                  issue['issue_key'],
                                  issue['issue_summary'],
                                  issue['assignee'])
        )
  result['closed_jira_count'] = len(resolved_jiras)
  result['closed_jira'] = closed_jiras

  if conf.json:
    print(json.dumps(result, indent=4))

  if conf.html:
    print(make_html(result))

if __name__ == '__main__':
  try:
    main()
  except KeyboardInterrupt:
    print('\nReceived Ctrl-C, exiting early')
