#!/usr/bin/env python

# 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.

"""Usage: release_notes.py <version> > RELEASE_NOTES.html

Generates release notes for a Kafka release by generating an HTML doc containing some introductory information about the
 release with links to the Kafka docs followed by a list of issues resolved in the release. The script will fail if it finds
 any unresolved issues still marked with the target release. You should run this script after either resolving all issues or
 moving outstanding issues to a later release.

"""

from jira import JIRA
import itertools, sys

if len(sys.argv) < 2:
    print >>sys.stderr, "Usage: release_notes.py <version>"
    sys.exit(1)

version = sys.argv[1]
minor_version_dotless = "".join(version.split(".")[:2]) # i.e., 10 if version == 1.0.1

JIRA_BASE_URL = 'https://issues.apache.org/jira'
MAX_RESULTS = 100 # This is constrained for cloud instances so we need to fix this value

def get_issues(jira, query, **kwargs):
    """
    Get all issues matching the JQL query from the JIRA instance. This handles expanding paginated results for you. Any additional keyword arguments are forwarded to the JIRA.search_issues call.
    """
    results = []
    startAt = 0
    new_results = None
    while new_results == None or len(new_results) == MAX_RESULTS:
        new_results = jira.search_issues(query, startAt=startAt, maxResults=MAX_RESULTS, **kwargs)
        results += new_results
        startAt += len(new_results)
    return results

def issue_link(issue):
    return "%s/browse/%s" % (JIRA_BASE_URL, issue.key)


if __name__ == "__main__":
    apache = JIRA(JIRA_BASE_URL)
    issues = get_issues(apache, 'project=KAFKA and fixVersion=%s' % version)
    if not issues:
        print >>sys.stderr, "Didn't find any issues for the target fix version"
        sys.exit(1)

    # Some resolutions, including a lack of resolution, indicate that the bug hasn't actually been addressed and we shouldn't even be able to create a release until they are fixed
    UNRESOLVED_RESOLUTIONS = [None,
                              "Unresolved",
                              "Duplicate",
                              "Invalid",
                              "Not A Problem",
                              "Not A Bug",
                              "Won't Fix",
                              "Incomplete",
                              "Cannot Reproduce",
                              "Later",
                              "Works for Me",
                              "Workaround",
                              "Information Provided"
                              ]
    unresolved_issues = [issue for issue in issues if issue.fields.resolution in UNRESOLVED_RESOLUTIONS or issue.fields.resolution.name in UNRESOLVED_RESOLUTIONS]
    if unresolved_issues:
        print >>sys.stderr, "The release is not completed since unresolved issues or improperly resolved issues were found still tagged with this release as the fix version:"
        for issue in unresolved_issues:
            print >>sys.stderr, "Unresolved issue: %15s %20s %s" % (issue.key, issue.fields.resolution, issue_link(issue))
        print >>sys.stderr
        print >>sys.stderr, "Note that for some resolutions, you should simply remove the fix version as they have not been truly fixed in this release."
        sys.exit(1)

    # Get list of (issue type, [issues]) sorted by the issue ID type, with each subset of issues sorted by their key so they
    # are in increasing order of bug #. To get a nice ordering of the issue types we customize the key used to sort by issue
    # type a bit to ensure features and improvements end up first.
    def issue_type_key(issue):
        if issue.fields.issuetype.name == 'New Feature':
            return -2
        if issue.fields.issuetype.name == 'Improvement':
            return -1
        return issue.fields.issuetype.id
    by_group = [(k,sorted(g, key=lambda issue: issue.id)) for k,g in itertools.groupby(sorted(issues, key=issue_type_key), lambda issue: issue.fields.issuetype.name)]

    print "<h1>Release Notes - Kafka - Version %s</h1>" % version
    print """<p>Below is a summary of the JIRA issues addressed in the %(version)s release of Kafka. For full documentation of the
    release, a guide to get started, and information about the project, see the <a href="http://kafka.apache.org/">Kafka
    project site</a>.</p>

    <p><b>Note about upgrades:</b> Please carefully review the
    <a href="http://kafka.apache.org/%(minor)s/documentation.html#upgrade">upgrade documentation</a> for this release thoroughly
    before upgrading your cluster. The upgrade notes discuss any critical information about incompatibilities and breaking
    changes, performance changes, and any other changes that might impact your production deployment of Kafka.</p>

    <p>The documentation for the most recent release can be found at
    <a href="http://kafka.apache.org/documentation.html">http://kafka.apache.org/documentation.html</a>.</p>""" % { 'version': version, 'minor': minor_version_dotless }
    for itype, issues in by_group:
        print "<h2>%s</h2>" % itype
        print "<ul>"
        for issue in issues:
            print '<li>[<a href="%(link)s">%(key)s</a>] - %(summary)s</li>' % {'key': issue.key, 'link': issue_link(issue), 'summary': issue.fields.summary}
        print "</ul>"
