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

import datetime
import urllib
import yaml
import codecs as _codecs

from datetime import datetime
from xml.sax.saxutils import escape as escape_html

def write_utf8(file, string):
    with _codecs.open(file, encoding="utf-8", mode="w") as f:
        f.write(string)

    return file

def get_date_string():
    return datetime.today().strftime('%Y-%m-%d')

def render_release_notes(project, release):
    issues = _fetch_issues(project, release)
    lines = list()

    bugs = _render_issues(issues, "Bug")
    new_features = _render_issues(issues, "New Feature")
    improvements = _render_issues(issues, "Improvement")
    tests = _render_issues(issues, "Test")
    tasks = _render_issues(issues, "Task")
    dependencies = _render_issues(issues, "Dependency upgrade")

    if bugs is not None:
        lines.append("\n## Bugs Fixed\n")
        lines.append(bugs)

    if new_features is not None:
        lines.append("\n## New Features\n")
        lines.append(new_features)

    if improvements is not None:
        lines.append("\n## Improvements\n")
        lines.append(improvements)

    if tests is not None:
        lines.append("\n## Tests\n")
        lines.append(tests)

    if tasks is not None:
        lines.append("\n## Tasks\n")
        lines.append(tasks)

    if dependencies is not None:
        lines.append("\n## Dependency Upgrades\n")
        lines.append(dependencies)

    return "\n".join(lines)

def _fetch_issues(project, release):
    query = list()

    query.append("project = '{}'".format(project))
    query.append("fixVersion = '{}'".format(release))
    query.append("resolution = 'fixed'")

    query = " and ".join(query)
    query = "{} order by key asc".format(query)

    page_size = 100

    params = {
        "jql": query,
        "fields": "summary,issuetype",
        "maxResults": page_size,
        }

    issues = list()

    for i in range(100):
        params["startAt"] = i * page_size

        url = "https://issues.apache.org/jira/rest/api/2/search?{}".format(urllib.parse.urlencode(params))
        filename, headers = urllib.request.urlretrieve(url)

        with open(filename) as f:
            data = yaml.load(f, Loader=yaml.Loader)

        issues.extend(data["issues"])

        if len(issues) >= int(data["total"]):
            break

    return issues

def _render_issues(issues, *types):
    filtered_issues = [x for x in issues
                       if x["fields"]["issuetype"]["name"] in types]

    if not filtered_issues:
        return None

    lines = list()

    for issue in filtered_issues:
        key = escape_html(issue["key"])
        url = "https://issues.apache.org/jira/browse/{}".format(key)
        summary = escape_html(issue["fields"]["summary"])

        lines.append("* [{}]({}) - {}".format(key, url, summary))

    return "\n".join(lines)

