#!/usr/bin/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.
#

from generate import *

from datetime import datetime

download_records = (
    ("apache-qpid-proton-j-{}-bin.tar.gz", "Qpid Proton-J (binary)"),
    ("apache-qpid-proton-j-{}-src.tar.gz", "Qpid Proton-J (source release)"),
    )

documentation = \
"""
<div class="two-column" markdown="1">

 - [API reference](api/index.html)
 - [Examples](https://github.com/apache/qpid-proton-j/tree/{source_release}/examples)

</div>
"""

template = \
"""
;;
;; 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.
;;

# Qpid Proton-J {release}

Qpid Proton is a high-performance, lightweight messaging library. More
about [Qpid Proton]({{{{site_url}}}}/proton/index.html).

For a detailed list of the changes in this release, see the [release
notes](release-notes.html).

## Download

It's important to [verify the
integrity]({{{{site_url}}}}/download.html#verify-what-you-download) of
the files you download.

| Content | Download | Verify |
|---------|----------|--------|
{downloads}

Proton-J is also available [via Maven]({{{{site_url}}}}/maven.html).

## Documentation

{documentation}

## More information

 - [All release artefacts](https://archive.apache.org/dist/qpid/proton-j/{release})
 - [Resolved issues in JIRA]({issues_url})
 - [Source repository tag](https://gitbox.apache.org/repos/asf?p=qpid-proton-j.git;a=tag;h={release})

<script type="text/javascript">
  _deferredFunctions.push(function() {{
      if ("{release}" === "{{{{current_proton_j_release}}}}") {{
          _modifyCurrentReleaseLinks();
      }}
  }});
</script>
"""

def gen_release_page(release, issues_release, source_release, release_dir):
    output_path = join(release_dir, "index.md")

    downloads = list()
    artifact_url_template = "https://archive.apache.org/dist/qpid/proton-j/{}/{}"

    for artifact, summary in download_records:
        artifact = artifact.format(release)
        artifact_url = artifact_url_template.format(release, artifact)
        asc_url = "{}.asc".format(artifact_url)
        sha_url = "{}.sha512".format(artifact_url)

        args = summary, artifact, artifact_url, asc_url, sha_url
        downloads.append("| {} | [{}]({}) | [ASC]({}), [SHA512]({}) |".format(*args))

    downloads = "\n".join(downloads)

    jql = "project = PROTON AND fixVersion = 'proton-j-{}' AND resolution = 'fixed' ORDER BY priority DESC".format(issues_release)
    issues_url = "https://issues.apache.org/jira/issues/?jql={}".format(urllib.parse.quote_plus(jql))

    vars = locals()
    vars["documentation"] = documentation.format(release=release, source_release=source_release)

    output = template.format(**vars)
    output = output.strip()

    write(output_path, output)

main_template = """
;;
;; 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.
;;

# Qpid Proton documentation snapshot

<div class="feature" markdown="1">

## Warning! This is a snapshot of work in progress

Documentation found here may be incorrect or incomplete.  For a
smoother experience, see the [current stable
release]({{{{current_proton_j_release_url}}}}/index.html).

This content was generated at {time} on {day}, {date}.

</div>

## Documentation

{documentation}

## More information

 - [Source repository](https://gitbox.apache.org/repos/asf/qpid-proton-j.git?a=tree)
"""

def gen_main_release_page(release_dir):
    output_path = join(release_dir, "index.md")

    now = datetime.now()

    day = now.strftime("%A")
    date = now.strftime("%d %B %Y")
    time = now.strftime("%H:%M %Z")

    vars = locals()
    vars["documentation"] = documentation.format(release="main", source_release="main")

    output = main_template.format(**vars)
    output = output.strip()

    write(output_path, output)

release, issues_release, source_release, release_dir, checkout_dir = setup_release_script()

if release == "main":
    gen_main_release_page(release_dir)
else:
    gen_release_page(release, issues_release, source_release, release_dir)

notice("Release page generated")
