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


"""
This script creates a release candidate and relevant files.

(How to run)
python release.py <reef_home> <reef_version> <rc candidate number> <public key id (8 hex numbers)>

You can also see how to run the script with 'python release.py -h'

(Examples)
python release.py ~/reef 0.14.0 1 E488F925

"""


import subprocess
import fnmatch
import tarfile
import hashlib
import os
import argparse

"""
Get list from .gitignore
"""
def get_ignore_list(reef_home):
    f = open(reef_home + "/.gitignore", "r")
    if f is None:
        return []

    ignore_list = list()

    while True:
        line = f.readline()[:-1]
        if not line:
            break
        if "#" not in line:
            ignore_list.insert(0, "*/" + line)

    return ignore_list

"""
Make text for e-mail
"""
def get_mail_text(reef_version, rc_num):
    file_name = "apache-reef-" + reef_version + "-rc" + str(rc_num) + ".tar.gz"

    return_str = ""
    return_str += "This is to call for a new vote for the source release of Apache REEF " \
        + reef_version + " (rc" + str(rc_num) + ").\n\n"
    return_str += "The source tar ball, including signatures, digests, etc can be found at:\n" + "<yours>\n\n"
    return_str += "The Git tag is release-" + reef_version + "-rc" + str(rc_num) + "\n"
    return_str += "The Git commit ID is <Git Commit ID>\n\n\n"

    return_str += "Checksums of apache-reef-" + reef_version + "-rc" + str(rc_num) + ".tar.gz:\n\n"

    md5 = open(file_name + ".md5").read().split(" ")[0]
    return_str += "MD5: " + md5 + "\n"
    
    sha = open(file_name + ".sha512.txt").read().split(" ")[0]
    return_str += "SHA: " + sha + "\n"

    return_str += "\nRelease artifacts are signed with a key found in the KEYS file available here:\n"
    return_str += "\nhttps://dist.apache.org/repos/dist/release/reef/KEYS\n\n\n\n"

    return_str += "<Issue Things>\n\n\n\n"

    return_str += "The vote will be open for 72 hours. Please download the release\n" \
        + "candidate, check the hashes/signature, build it and test it, and then\nplease vote:\n\n" \
        + "[ ] +1 Release this package as Apache REEF " + reef_version + "\n" \
        + "[ ] +0 no opinion\n" \
        + "[ ] -1 Do not release this package because ...\n\n" \
        + "Thanks!"

    return return_str

"""
Function to exclude files in .gitignore when making tar.gz
Return true when a file is in .gitignore
"""
def exclude_git_ignore(file_name):
    ignore_list = get_ignore_list(reef_home)
    for e in ignore_list:
        if fnmatch.fnmatch(file_name, e):
            return True

    return fnmatch.fnmatch(file_name, "*/.git") or fnmatch.fnmatch(file_name, "*/.gitignore") or \
        fnmatch.fnmatch(file_name, "*/.gitattributes")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Script for release versioning, packaging, checksum")
    
    parser.add_argument("reef_home", type=str, help="REEF home")
    parser.add_argument("reef_version", type=str, help="REEF version")
    parser.add_argument("rc_num", type=int, help ="rc candidate number")
    parser.add_argument("key_id", type=str, help = "public key id (8 hex numbers)")
    args = parser.parse_args()
    
    reef_home = os.path.abspath(args.reef_home)
    reef_version = args.reef_version
    rc_num = args.rc_num
    key_id = args.key_id

    build_result = subprocess.call("cd " + reef_home + " && " + "mvn apache-rat:check", shell=True)

    if build_result == 0:
        file_name = "apache-reef-" + reef_version + "-rc" + str(rc_num) + ".tar.gz"

        # Make tar.gz
        tar = tarfile.open(file_name, "w:gz")
        tar.add(reef_home, arcname="apache-reef-"+reef_version, exclude=exclude_git_ignore)
        tar.close()

        gpg_str = "gpg --armor -u " + str(key_id) + " --output " + file_name + ".asc " + "--detach-sig " + file_name
        gpg_result = subprocess.call(gpg_str, shell=True)

        if gpg_result == 0:
            md5 = hashlib.md5(open(file_name, 'rb').read()).hexdigest()
            sha = hashlib.sha512(open(file_name, 'rb').read()).hexdigest()

            md5_file = open(file_name + ".md5", "w")
            md5_file.write(md5 + " *" + file_name + "\n")
            sha_file = open(file_name + ".sha512.txt", "w")
            sha_file.write(sha + " *" + file_name + "\n")
            md5_file.close()
            sha_file.close()

            # Make a Text for an e-mail
            print "\n==================================Result==================================="
            print get_mail_text(reef_version, rc_num)
            print "===========================================================================\n"

        else:
            print "gpg error"

    else:
        print "build error - mvn apache-rat:check failed"
