#!/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 = (
    ("qpid-interop-test-{}.tar.gz", "Interop Test"),
)

component_records = (
    ("qpid-interop-test", "Interop Test", "-", "Linux", "1.0"),
)

documentation = \
"""
 - [Quickstart guide](QUICKSTART.html)
 - [User guide](users-guide.html)
 - [Developer overview](https://gitbox.apache.org/repos/asf?p=qpid-interop-test.git;a=blob_plain;f=docs/qpid-interop-test-devel-overview.txt;hb=0.1.0)
 - [Test HOWTO](https://gitbox.apache.org/repos/asf?p=qpid-interop-test.git;a=blob_plain;f=docs/Test_HOWTO.txt;hb=0.1.0)
 - [Shim HOWTO](https://gitbox.apache.org/repos/asf?p=qpid-interop-test.git;a=blob_plain;f=docs/Shim_HOWTO.txt;hb=0.1.0)
"""

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 Interop Test {release}

Qpid Interop Test is a suite of AMQP interoperability tests.  More
about [Qpid Interop
Test]({{{{site_url}}}}/components/interop-test/index.html).

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

## Downloads

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

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

## Documentation

{documentation}

## More information

 - [All release artefacts](https://archive.apache.org/dist/qpid/interop-test/{release})
 - [Resolved issues in JIRA]({issues_url})
 - [Source repository tag](https://gitbox.apache.org/repos/asf/qpid-interop-test.git/tree/refs/tags/{release})

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

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

    downloads = list()
    components = list()

    artifact_url_template = "https://archive.apache.org/dist/qpid/interop-test/{}/{}"

    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))

    for key, name, languages, platforms, amqp_versions in component_records:
        link = "[{}]({{{{site_url}}}}/components/{}/index.html)".format(name, key)
        args = link, languages, platforms, amqp_versions
        components.append("| {} | {} | {} | {} |".format(*args))

    downloads = "\n".join(downloads)
    components = "\n".join(components)

    jql = "project = QPIDIT AND fixVersion = '{}' 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 Interop Test 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_interop_test_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-interop-test.git)
"""

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")
