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

# Create changelist for any two branches/tags

# Prequisites:
# The old version has to be installed in the "madlib_old_vers" schema
# The new version has to be installed in the "madlib" (default) schema
# Two branches/tags must exist locally (run 'git fetch' to ensure you have the latest version)
# The current branch does not matter

# Usage (must be executed in the src/madpack directory):
# python create_changelist.py <database name> <old version branch> <new version branch> <changelist filename>
# If you are using the master branch, please make sure to edit the branch/tag in the output file

# Example (should be equivalent to changelist_1.13_1.14.yaml):
# python create_changelist.py madlib rel/v1.13 rel/v1.14 chtest1.yaml

import sys
import os

database = sys.argv[1]
old_vers = sys.argv[2]
new_vers = sys.argv[3]
ch_filename = sys.argv[4]

if os.path.exists(ch_filename):
    print "{0} already exists".format(ch_filename)
    raise SystemExit

err1 = os.system("""psql {0} -l > /dev/null""".format(database))
if err1 != 0:
    print "Database {0} does not exist".format(database)
    raise SystemExit

err1 = os.system("""psql {0} -c "select madlib_old_vers.version()" > /dev/null
                 """.format(database))
if err1 != 0:
    print "MADlib is not installed in the madlib_old_vers schema. Please refer to the Prequisites."
    raise SystemExit

err1 = os.system("""psql {0} -c "select madlib.version()" > /dev/null
                 """.format(database))
if err1 != 0:
    print "MADlib is not installed in the madlib schema. Please refer to the Prequisites."
    raise SystemExit

print "Creating changelist {0}".format(ch_filename)
os.system("""
    rm -f /tmp/madlib_tmp_nm.txt \
    /tmp/madlib_tmp_udf.txt \
    /tmp/madlib_tmp_udt.txt \
    /tmp/madlib_tmp_udo.txt \
    /tmp/madlib_tmp_udoc.txt \
    /tmp/madlib_tmp_typedep.txt \
    /tmp/madlib_tmp_typedep_udo.txt \
    /tmp/madlib_tmp_typedep_udoc.txt
    """)
try:
    # Find the new modules using the git diff
    err1 = os.system("git diff {old_vers} {new_vers} --name-only --diff-filter=A > /tmp/madlib_tmp_nm.txt".format(**locals()))
    if err1 != 0:
        print "Git diff failed. Please ensure that branches/tags are fetched."
        raise SystemExit

    f = open("/tmp/madlib_tmp_cl.yaml", "w")
    f.write(
"""# ------------------------------------------------------------------------------
# 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.
# ------------------------------------------------------------------------------
""")

    f.write(
    """
# Changelist for MADlib version {old_vers} to {new_vers}

# This file contains all changes that were introduced in a new version of
# MADlib. This changelist is used by the upgrade script to detect what objects
# should be upgraded (while retaining all other objects from the previous version)

# New modules (actually .sql_in files) added in upgrade version
# For these files the sql_in code is retained as is with the functions in the
# file installed on the upgrade version. All other files (that don't have
# updates), are cleaned up to remove object replacements
""".format(**locals()))

    # Find the new .sql_in files that are not in test folders
    f.write("new module:\n")
    with open('/tmp/madlib_tmp_nm.txt') as fp:
        for line in fp:
            if 'sql_in' in line and '/test/' not in line:
                 f.write('    ' + line.split('/')[5].split('.')[0]+':\n')

    # Find the changed types and keep a list for future use
    os.system("psql {0} -f diff_udt.sql > /tmp/madlib_tmp_udt.txt".format(database))

    f.write("\n# Changes in the types (UDT) including removal and modification\n")
    f.write("udt:\n")
    udt_list=[]
    with open('/tmp/madlib_tmp_udt.txt') as fp:
        for line in fp:

            # Both the type and its array form shows up as separate types
            # We don't need both of them so we remove the array
            if 'UDT' in line and '[]' not in line:
                ch_type = line.split('|')[1].strip()
                udt_list.append(ch_type)
                f.write('    ' + ch_type +":\n")

    # Find the list of UDFs and UDAs
    # There are two main sources for these lists.
    # 1. The functions that actually got changed
    # 2. The functions that depend on a changed type

    # We will keep two lists (for UDF and UDA) and fill them as we parse the
    # output of diff functions

    udf_list=[]
    uda_list=[]
    current_list = udf_list

    # Find the changed functions/aggregates via the diff_udf script and write them to a file
    os.system("psql {0} -f diff_udf.sql > /tmp/madlib_tmp_udf.txt".format(database))

    # The entries in the file are ordered by type.
    # Read them line by line and add to the udf list until the first aggregate
    with open('/tmp/madlib_tmp_udf.txt') as fp:
        for line in fp:
            if 'type' in line:
                # When we get the first aggregate, we switch the current list
                if 'agg' in line:
                    current_list = uda_list
            if 'UDF' in line:
                current_list.append(line.split('|')[1])

    current_list = udf_list

    # Find the function that return a changed type
    # Note that we already ran the diff_udf.sql file
    # This means the get_functions() function is already defined in the database
    if os.path.exists("/tmp/madlib_tmp_typedep.txt"):
        os.system("rm /tmp/madlib_tmp_typedep.txt")
    os.system("touch /tmp/madlib_tmp_typedep.txt")
    for t in udt_list:

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        # Find all of the old functions that return this particular type t and write to a table
        os.system("""psql {database} -c "SELECT get_functions('__tmp__madlib__', 'madlib_old_vers', 'madlib_old_vers.{t}')" > /dev/null """.format(**locals()))

        # Order them in descending order on type so that we read the functions first and aggregates last
        os.system("""psql {database} -x -c "SELECT type, name, retype, argtypes FROM __tmp__madlib__ ORDER BY type DESC" > /tmp/madlib_tmp_typedep.txt """.format(**locals()))

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        with open('/tmp/madlib_tmp_typedep.txt') as fp:
            for line in fp:
                if '|' in line:
                    sp = line.split('|')

                    # Type is only used for switching the current list from udf to uda
                    if sp[0].strip() == 'type':
                        if sp[1].strip() == 'agg':
                            current_list = uda_list

                    # Add the functions with formatting
                    elif sp[0].strip() == 'name':
                        current_list.append('    - ' + sp[1].strip() + ":\n")
                    elif sp[0].strip() == 'retype':
                        current_list.append('        rettype: schema_madlib.' + sp[1].strip() + "\n")
                    elif sp[0].strip() == 'argtypes':
                        current_list.append('        argument: ' + sp[1].strip() + "\n")

    # Write the UDF and UDA lists to the changelist
    f.write(
    """
# List of the UDF changes that affect the user externally. This includes change
# in function name, return type, argument order or types, or removal of
# the function. In each case, the original function is as good as removed and a
# new function is created. In such cases, we should abort the upgrade if there
# are user views dependent on this function, since the original function will
# not be present in the upgraded version.
""")

    f.write("udf:\n")
    for line in udf_list:
        f.write(line)

    f.write("""
# Changes to aggregates (UDA) including removal and modification
# Overloaded functions should be mentioned separately
""")

    f.write("uda:\n")
    for line in uda_list:
        f.write(line)

    #TODO: We need to decide how we want to check for these
    f.write(
    """
# List of the UDC, UDO and UDOC changes.
""")
    f.write("udc:\n")

    # Find the changed operators

    f.write("\n# Changes in the operators (UDO)\n")
    f.write("udo:\n")

    os.system("psql {0} -f diff_udo.sql > /tmp/madlib_tmp_udo.txt".format(database))
    with open('/tmp/madlib_tmp_udo.txt') as fp:
        for line in fp:
            if ' | ' in line:
                    sp = line.split(' | ')

                    if sp[0].strip() == 'name':
                        f.write("    - '" + sp[1].strip() + "':\n")
                    elif sp[0].strip() == 'rettype':
                        f.write('        rettype: ' + sp[1].strip() + "\n")
                    elif sp[0].strip() == 'oprright':
                        f.write('        rightarg: ' + sp[1].strip() + "\n")
                    elif sp[0].strip() == 'oprleft':
                        f.write('        leftarg: ' + sp[1].strip() + "\n")

    for t in udt_list:

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        os.system("""psql {database} -c "SELECT get_udos('__tmp__madlib__', 'madlib_old_vers', '{t}')" > /dev/null """.format(**locals()))

        os.system("""psql {database} -x -c "SELECT name, rettype, oprright, oprleft FROM __tmp__madlib__ ORDER BY name DESC" > /tmp/madlib_tmp_typedep_udo.txt """.format(**locals()))

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        with open('/tmp/madlib_tmp_typedep_udo.txt') as fp:
            for line in fp:
                if '|' in line:
                    sp = line.split('|')

                    if sp[0].strip() == 'name':
                        f.write("    - '" + sp[1].strip() + "':\n")
                    elif sp[0].strip() == 'rettype':
                        f.write('        rettype: ' + sp[1].strip() + "\n")
                    elif sp[0].strip() == 'oprright':
                        f.write('        rightarg: ' + sp[1].strip() + "\n")
                    elif sp[0].strip() == 'oprleft':
                        f.write('        leftarg: ' + sp[1].strip() + "\n")


    # Find the changed operator classes

    f.write("\n# Changes in the operator classes (UDOC)\n")
    os.system("psql {0} -f diff_udoc.sql > /tmp/madlib_tmp_udoc.txt".format(database))
    f.write("udoc:\n")
    with open('/tmp/madlib_tmp_udoc.txt') as fp:
        for line in fp:
            if '|' in line:
                    sp = line.split('|')

                    if sp[0].strip() == 'opfamily_name':
                        f.write("    - '" + sp[1].strip() + "':\n")
                    elif sp[0].strip() == 'index_method':
                        f.write('        index_method: ' + sp[1].strip() + "\n")

    for t in udt_list:

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        os.system("""psql {database} -c "SELECT get_udocs('__tmp__madlib__', 'madlib_old_vers', '{t}')" > /dev/null """.format(**locals()))

        os.system("""psql {database} -x -c "SELECT opfamily_name, index_method FROM __tmp__madlib__ ORDER BY name DESC" > /tmp/madlib_tmp_typedep_udoc.txt """.format(**locals()))

        os.system("""psql {database} -c "DROP TABLE IF EXISTS __tmp__madlib__ " > /dev/null """.format(**locals()))

        with open('/tmp/madlib_tmp_typedep_udoc.txt') as fp:
            for line in fp:
                if '|' in line:
                    sp = line.split('|')

                    if sp[0].strip() == 'opfamily_name':
                        f.write("    - " + sp[1].strip() + ":\n")
                    elif sp[0].strip() == 'index':
                        f.write('        index: ' + sp[1].strip() + "\n")

    f.close()

    # Copy the new changelist file to its proper location
    # This helps to keep the madlib folder clean in case the program stops
    # unexpectedly
    os.system("cp /tmp/madlib_tmp_cl.yaml {0}".format(ch_filename))

except:
    print "Something went wrong! The changelist might be wrong/corrupted."
    raise
finally:
    os.system("""
        rm -f /tmp/madlib_tmp_nm.txt \
        /tmp/madlib_tmp_udf.txt \
        /tmp/madlib_tmp_udt.txt \
        /tmp/madlib_tmp_udo.txt \
        /tmp/madlib_tmp_udoc.txt \
        /tmp/madlib_tmp_typedep.txt \
        /tmp/madlib_tmp_typedep_udo.txt \
        /tmp/madlib_tmp_typedep_udoc.txt \
        /tmp/madlib_tmp_cl.yaml
        """)
