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

import argparse
try:
    import argcomplete
except ImportError:
    argcomplete = False
import os
import yaml
import json
import sys
import smtplib
import subprocess
from email.mime.text import MIMEText

class objectify(object):
    def __init__(self, d):
        self.__dict__ = d

def parseArgsAndConfig():
    parser = argparse.ArgumentParser(description='Generates Release Candidate Vote Email')
    parser.add_argument('-v', '--verbose', help='verbose output', action='store_true')
    parser.add_argument('-n', '--dryrun', help='verbose output', action='store_true')
    parser.add_argument('-mc', '--mail-conf', help='YAML configuration file for mailer', metavar='YAML', type=argparse.FileType('r'), required=False)
    parser.add_argument('-rc', '--rc-conf', help='JSON configuration file for release candidate', metavar='JSON', type=argparse.FileType('r'), required=True)
    parser.add_argument('-s', '--subject', help='Component name for subject line', metavar='NAME')
    parser.add_argument('-i', '--signature', help='Signature line to conclude email', metavar='SIGNATURE')

    if argcomplete:
        argcomplete.autocomplete(parser)

    args = parser.parse_args()

    args.rcConfig = json.load(args.rc_conf)
    if not args.dryrun:
      if 'mail_conf' not in args:
        parser.error("--mail-config required except for a dryrun.")

      args.mailConfig = yaml.load(args.mail_conf)
      if 'mail' not in args.mailConfig:
        print('Error: bad configuration, need "mail" properties.')
        return
      else:
        args.mailConfig = args.mailConfig['mail']
    else:
        args.mailConfig = None
    return args

def componentList(config, version):
    for r in config['RepoList']:
        key = r.replace('-', '_')
        hash = config[key]['hash']
        name = config[key]['name'] if 'name' in config[key] else '???'
        repo = config[key]['repository']
        yield objectify({
                'id': r,
                'hash': hash,
                'name': name,
                'url': repo[0:-4],
                'artifacts': artifactLinks(r, version.v, version.rc)
        })

def artifactLinks(name, version, rc):
    root = 'https://dist.apache.org/repos/dist/dev/openwhisk/apache-openwhisk-%s-%s' % (version, rc)
    tgz  = '%s-%s-sources.tar.gz' % (name, version)
    asc  = '%s.asc' % tgz
    sha  = '%s.sha512' % tgz
    return objectify({
       'tgz': '%s/%s' % (root, tgz),
       'asc': '%s/%s' % (root, asc),
       'sha': '%s/%s' % (root, sha)
    })

def currentGitHead():
    return subprocess.check_output(['git', 'show-ref', '--hash', '--abbrev', '--', 'refs/remotes/upstream/master']).strip()

def gitHashes(components):
    s = map(lambda r: "* %s: %s\n  %s/commits/%s\n  %s\n  %s\n  %s\n" % (r.name, r.hash, r.url, r.hash, r.artifacts.tgz, r.artifacts.asc, r.artifacts.sha), components)
    return '\n'.join(list(s))

def rcverify(components, version):
    s = map(lambda r: "rcverify.sh %s '%s' %s %s" % (r.id, r.name, version.v, version.rc), components)
    return '\n'.join(list(s))

def releaseVersion(config):
    return objectify({
            'v': config['versioning']['version'],
            'rc': config['versioning']['pre_release_version']
    })

def sendVoteEmail(mailConfig, rcConfig, dryrun, subjectLineId, signature):
    version = releaseVersion(rcConfig)
    components = list(componentList(rcConfig, version))
    componentsString = ', '.join(map(lambda c: c.name, components))
    componentCount = len(components)

    subject = '[VOTE] Release Apache %s (v%s, %s)' % (subjectLineId if subjectLineId else componentsString, version.v, version.rc)
    content = """Hi,

This is a call to vote on releasing version {version} release candidate {rc} of the following {N} with artifacts built from the Git repositories and commit IDs listed below.

{githashes}
This release is comprised of source code distribution only.

You can use this UNIX script to download the release and verify the checklist below:
https://gitbox.apache.org/repos/asf?p=incubator-openwhisk-release.git;a=blob_plain;f=tools/rcverify.sh;hb={HEAD}

Usage:
curl -s "https://gitbox.apache.org/repos/asf?p=incubator-openwhisk-release.git;a=blob_plain;f=tools/rcverify.sh;hb={HEAD}" -o rcverify.sh
chmod +x rcverify.sh
{rcverifies}

Please vote to approve this release:

  [ ] +1 Approve the release
  [ ]  0 Don't care
  [ ] -1 Don't release, because ...

Release verification checklist for reference:
  [ ] Download links are valid.
  [ ] Checksums and PGP signatures are valid.
  [ ] DISCLAIMER is included.
  [ ] Source code artifacts have correct names matching the current release.
  [ ] LICENSE and NOTICE files are correct for each OpenWhisk repository.
  [ ] All files have license headers as specified by OpenWhisk project policy [1].
  [ ] No compiled archives bundled in source archive.

This majority vote is open for at least 72 hours.
{signature}

[1] https://github.com/apache/incubator-openwhisk-release/blob/master/docs/license_compliance.md""".format(
        version = version.v,
        rc = version.rc,
        N = ("%s project modules" % componentCount) if componentCount > 1 else "project module",
        HEAD = currentGitHead(),
        githashes = gitHashes(components),
        rcverifies = rcverify(components, version),
        signature = ("\n%s" % signature) if signature else "")

    if (dryrun):
      print(subject)
      print(content)
      return

    print('Sending email: %s -> %s' % (mailConfig['from'], mailConfig['to']))

    msg = MIMEText(content, _charset='utf-8')
    msg['From'] = mailConfig['from']
    msg['To'] = mailConfig['to']
    msg['Subject'] = subject
    server = smtplib.SMTP(mailConfig['smtp'])
    if mailConfig['useTLS']:
        server.starttls()
    if 'username' in mailConfig:
        server.login(mailConfig['username'], mailConfig['password'])

    server.sendmail(mailConfig['from'], mailConfig['to'], msg.as_string())
    server.quit()

def main(args):
  sendVoteEmail(args.mailConfig, args.rcConfig, args.dryrun, args.subject, args.signature)

if __name__ == "__main__":
  args = parseArgsAndConfig()
  if args:
    main(args)
  else:
    sys.exit(-1)
