#!/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

source_artefact_records = (
    ("qpid-cpp-{}.tar.gz", "C++ broker, Qpid Messaging API (C++)"),
)

component_records = (
    ("cpp-broker", "C++ broker", "C++", "Linux, Windows", "1.0, 0-10"),
    ("messaging-api", "Qpid Messaging API", "C++", "Linux, Windows", "1.0, 0-10"),
)

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

 - [Installing Qpid C++](https://gitbox.apache.org/repos/asf?p=qpid-cpp.git;a=blob_plain;f=INSTALL.txt;hb=HEAD)
 - [C++ broker book](cpp-broker/book/index.html) ([PDF](cpp-broker/cpp-broker-book.pdf))
 - [Using the Qpid Messaging API](messaging-api/book/using-the-qpid-messaging-api.html) ([PDF](messaging-api/qpid-messaging-api-book.pdf))
 - [C++ API reference](messaging-api/cpp/api/index.html)
 - [C++ examples](messaging-api/cpp/examples/index.html)

</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 C++ {release}

Qpid C++ offers a connection-oriented messaging API and a message
broker written in C++ that stores, routes, and forwards messages using
AMQP. More about [Qpid]({{{{site_url}}}}/index.html).

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

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

## Source archives

| Content | Download | Verify |
|---------|----------|--------|
{source_artefacts}

## Components

| Component | Languages | Platforms | AMQP versions |
|-----------|-----------|-----------|---------------|
{components}

## Documentation

{documentation}

## More information

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

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

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

    components = list()

    source_artefacts = list()
    artefact_url_template = "https://archive.apache.org/dist/qpid/cpp/{}/{}"

    for artefact, summary in source_artefact_records:
        artefact = artefact.format(release)
        artefact_url = artefact_url_template.format(release, artefact)
        asc_url = "{}.asc".format(artefact_url)
        sha_url = "{}.sha512".format(artefact_url)

        args = summary, artefact, artefact_url, asc_url, sha_url
        row = "| {} | [{}]({}) | [ASC]({}), [SHA512]({}) |".format(*args)

        source_artefacts.append(row)

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

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

    jql = "project = QPID AND fixVersion = 'qpid-cpp-{}' 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

    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 C++ 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_cpp_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-cpp.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
    
    output = main_template.format(**vars)
    output = output.strip()

    write(output_path, output)

## Now do stuff ##

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