# coding=utf-8
#
# 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 ast
import dill
import os
import plpy
from collections import defaultdict
from math import ceil

import madlib_keras_serializer
import madlib_keras_gpu_info
from madlib_keras_custom_function import CustomFunctionSchema
from madlib_keras_custom_function import update_builtin_metrics

from utilities.utilities import _assert
from utilities.utilities import is_platform_pg

import tensorflow as tf
from tensorflow.keras import backend as K
from tensorflow.keras import utils as keras_utils
from tensorflow.keras.optimizers import *

import tensorflow.keras.optimizers as opt
import tensorflow.keras.losses as losses
import tensorflow.keras.metrics as metrics

CUDA_VISIBLE_DEVICES_KEY = 'CUDA_VISIBLE_DEVICES'
#######################################################################
########### Keras specific functions #####
#######################################################################

def set_cuda_env(value):
    """
    :param value: -1 to disable gpu
    :return:
    """
    os.environ[CUDA_VISIBLE_DEVICES_KEY] = value

def reset_cuda_env(value):
    """
    This function will reset the cuda env variable. This should only be called
    if set_cuda_env was called previously.
    :param value:
    """
    if value:
        set_cuda_env(value)
    else:
        if CUDA_VISIBLE_DEVICES_KEY in os.environ:
            del os.environ[CUDA_VISIBLE_DEVICES_KEY]

def enable_xla():
    os.environ['TF_XLA_FLAGS'] = '--tf_xla_auto_jit=2 --tf_xla_cpu_global_jit'
    try:
        tf.config.optimizer.set_jit(True)
    except:
        plpy.warning("This version of tensorflow does not fully support XLA auto-cluster JIT optimization.  HINT:  upgrading to tensorflow 1.14.0 may improve performance.")

def get_device_name_and_set_cuda_env(gpu_count, seg):
    if gpu_count > 0:
        device_name = '/gpu:0'
        if is_platform_pg():
            cuda_visible_dev = ','.join([str(i) for i in range(gpu_count)])
        else:
            cuda_visible_dev = str(seg % gpu_count)
        set_cuda_env(cuda_visible_dev)
    else: # cpu only
        device_name = '/cpu:0'
        set_cuda_env('-1')
    return device_name

def set_keras_session(device_name, gpu_count, segments_per_host):
    session = get_keras_session(device_name, gpu_count, segments_per_host)
    K.set_session(session)

def get_keras_session(device_name, gpu_count, segments_per_host):
    config = tf.ConfigProto()
    if gpu_count > 0:
        memory_fraction = get_gpu_memory_fraction(gpu_count, segments_per_host)
        config.gpu_options.allow_growth = False
        config.gpu_options.per_process_gpu_memory_fraction = memory_fraction
    session = tf.Session(config=config)
    enable_xla()
    return session

def clear_keras_session(sess = None):
    if sess is None:
        sess = K.get_session()
    K.clear_session()
    sess.close()


def get_gpu_memory_fraction(gpu_count, segments_per_host):
    """
    We cap the gpu memory usage to 90% of the total available gpu memory.
    This 90% is evenly distributed among the segments per gpu.
    :param gpu_count:
    :param segments_per_host:
    :return:
    """
    return 0.9 / ceil(1.0 * segments_per_host / gpu_count)

def get_model_shapes(model):
    model_shapes = []
    for a in model.get_weights():
        model_shapes.append(a.shape)
    return model_shapes

def compile_and_set_weights(segment_model, compile_params, device_name,
                            serialized_weights):
    model_shapes = get_model_shapes(segment_model)
    compile_model(segment_model, compile_params)
    model_weights = madlib_keras_serializer.deserialize_as_nd_weights(
        serialized_weights, model_shapes)
    segment_model.set_weights(model_weights)

# TODO: This can be refactored to be part of compile_and_set_weights(),
# by making compile_params an optional param in that function. Doing that
# now might create more merge conflicts with other JIRAs, so get to this later.
def set_model_weights(segment_model, serialized_weights):
    model_shapes = get_model_shapes(segment_model)
    model_weights = madlib_keras_serializer.deserialize_as_nd_weights(
        serialized_weights, model_shapes)
    segment_model.set_weights(model_weights)

"""
Used to convert compile_params and fit_params to actual argument dictionaries
"""

def convert_string_of_args_to_dict(str_of_args):
    """Uses parenthases matching algorithm to intelligently convert
    a string with valid python code into an argument dictionary"""
    stack = []
    dual = {
        '(' : ')',
        '[' : ']',
        '{' : '}',
    }
    result_str = ""
    key_str = ""
    compile_dict = {}
    for char in str_of_args:
        if char in dual.keys():
            stack.append(char)
            result_str += char
        elif char in dual.values() and stack:
            if dual[stack[-1]] == char:
                stack.pop(-1)
            result_str += char
        elif not stack and char == "=":
            key_str = result_str
            result_str = ""
        elif not stack and char == ",":
            value_str = result_str
            result_str = ""
            compile_dict[key_str.strip()]=value_str.strip().strip('\'')
        else:
            result_str += char
    value_str = result_str
    compile_dict[key_str.strip()]=value_str.strip().strip('\'')
    return compile_dict

def get_metrics_from_compile_param(str_of_args):
    compile_dict = convert_string_of_args_to_dict(str_of_args)
    metrics = None
    ckey = 'metrics'
    if ckey in compile_dict:
        try:
            metrics = ast.literal_eval(compile_dict[ckey])
        except ValueError:
            plpy.error(("Invalid input value for parameter {0}, "
                        "please refer to the documentation").format(ckey))
    return metrics

def get_loss_from_compile_param(str_of_args):
    compile_dict = convert_string_of_args_to_dict(str_of_args)
    loss = None
    if 'loss' in compile_dict:
        loss = compile_dict['loss']
    else:
        plpy.error(("Invalid input value for parameter 'loss', "
                    "please refer to the documentation"))
    return loss

# Parse the compile parameters and the optimizer.
def parse_and_validate_compile_params(str_of_args, additional_params=[]):
    """
    Args:
        @param: str_of_args     The string of arguments given by the user
    Returns:
        opt_name:               Name of the optimizer
        opt_args:               Arguments for the optimizer
        compile_dict:           Dictionary of arguments for keras.compile
    """
    literal_eval_compile_params = ['metrics', 'loss_weights',
                                   'weighted_metrics', 'sample_weight_mode']
    accepted_compile_params = literal_eval_compile_params + ['optimizer', 'loss'] + additional_params

    compile_dict = convert_string_of_args_to_dict(str_of_args)
    compile_dict = validate_and_literal_eval_keys(compile_dict,
                                                  literal_eval_compile_params,
                                                  accepted_compile_params)
    if len(additional_params) == 0:
        # optimizer is not a required parameter for keras compile
        _assert('optimizer' in compile_dict, "optimizer is a required parameter for compile")
        opt_name, opt_args = parse_optimizer(compile_dict)
    else:
        opt_name, opt_args = None, None

    _assert('loss' in compile_dict, "loss is a required parameter for compile")
    unsupported_loss_list = ['sparse_categorical_crossentropy']
    _assert(compile_dict['loss'] not in unsupported_loss_list,
            "Loss function {0} is not supported.".format(compile_dict['loss']))
    validate_compile_param_types(compile_dict)
    _validate_metrics(compile_dict)
    return (opt_name, opt_args, compile_dict)

def _validate_metrics(compile_dict):
    _assert('metrics' not in compile_dict.keys() or
            compile_dict['metrics'] is None or
            type(compile_dict['metrics']) is list,
            "wrong input type for compile parameter metrics: multi-output model"
            "are not supported yet, please pass a list")
    if 'metrics' in compile_dict and compile_dict['metrics']:
        unsupported_metrics_list = ['sparse_categorical_accuracy',
                                    'sparse_categorical_crossentropy',
                                    'sparse_top_k_categorical_accuracy']
        _assert(len(compile_dict['metrics']) == 1,
                "Only one metric at a time is supported.")
        _assert(compile_dict['metrics'][0] not in unsupported_metrics_list,
                "Metric {0} is not supported.".format(compile_dict['metrics'][0]))

# Parse the optimizer name and params.
def parse_optimizer(compile_dict):
    """
    Args:
        @param: compile_dict    Dictionary of arguments for keras.compile
    Returns:
        opt_name:               Name of the optimizer
        opt_args:               Arguments for the optimizer
    """
    opt_split = compile_dict['optimizer'].split('(')
    opt_name = opt_split[0]
    optimizers = get_optimizers()
    _assert(opt_name.lower() in [o.lower() for o in optimizers.keys()],
            "model_keras error: invalid optimizer name: {0}".format(opt_name))

    # If we use only the optimizer name
    if len(opt_split) == 1:
        final_args = None
    # If we use optimizer object with no params
    elif opt_split[1] == ')':
        final_args = None
    # If we give parameters to the optimizer
    else:
        opt_params = opt_split[1][:-1]
        opt_params_array = opt_params.split(',')
        opt_params_clean = map(split_and_strip, opt_params_array)
        key_value_params = { x[0] : x[1] for x in opt_params_clean}

        final_args = {}
        for key,value in key_value_params.iteritems():
            if value == 'None':
                final_args[key] = None
            elif value == 'True' or value == 'False':
                final_args[key] = bool(value)
            else:
                final_args[key] = float(value)
    return (opt_name,final_args)


# Parse the fit parameters into a dictionary.
def parse_and_validate_fit_params(fit_param_str):

    if fit_param_str:
        fit_params_dict = convert_string_of_args_to_dict(fit_param_str)

        literal_eval_fit_params = ['batch_size','epochs','verbose',
                                   'class_weight','initial_epoch','steps_per_epoch']
        accepted_fit_params = literal_eval_fit_params + ['shuffle']

        fit_params_dict = validate_and_literal_eval_keys(fit_params_dict,
                                                         literal_eval_fit_params,
                                                         accepted_fit_params)
        if 'shuffle' in fit_params_dict:
            shuffle_value = fit_params_dict['shuffle']
            if shuffle_value == 'True' or shuffle_value == 'False':
                fit_params_dict['shuffle'] = bool(shuffle_value)

        return fit_params_dict
    else:
        return {}

# Validate the keys of the given dictionary and run literal_eval on the
# user-defined subset
def validate_and_literal_eval_keys(keys_dict, literal_eval_list, accepted_list):
    for ckey in keys_dict.keys():
        _assert(ckey in accepted_list,
                "{0} is not currently accepted as a parameter. ".format(ckey))
        if ckey in literal_eval_list:
            try:
                keys_dict[ckey] = ast.literal_eval(keys_dict[ckey])
            except ValueError:
                plpy.error(("invalid input value for parameter {0}, "
                            "please refer to the documentation").format(ckey))
    return keys_dict

# Split and strip the whitespace of key=value formatted strings
def split_and_strip(x):
    y = x.split('=')
    return (y[0].strip(),y[1].strip())

# Return the list of keras optimizers
def get_optimizers():
    optimizers = dict()
    names = dir(opt)
    for n in names:
        optimizer = eval('opt.' + n)
        if isinstance(optimizer.__class__,type) and \
            '__module__' in dir(optimizer) and \
            'tensorflow.python.keras.optimizer' in optimizer.__module__:
            optimizers[n] = optimizer
    return optimizers

# Run the keras.compile with the given parameters
def compile_model(model, compile_params, custom_function_map=None):
    optimizers = get_optimizers()
    (opt_name,final_args,compile_dict) = parse_and_validate_compile_params(compile_params)
    if custom_function_map is not None:
        local_map=dill.loads(custom_function_map)

        compile_dict['loss']=local_map[compile_dict['loss']] \
            if compile_dict['loss'] in local_map else compile_dict['loss']

        new_metrics = []
        for i in compile_dict['metrics']:
            if i in local_map:
                new_metrics.append(local_map[i])
            else:
                new_metrics.append(i)
        compile_dict['metrics'] = new_metrics

    compile_dict['optimizer'] = optimizers[opt_name](**final_args) if final_args else opt_name
    model.compile(**compile_dict)

def validate_compile_param_types(compile_dict):
    _assert('loss_weights' not in compile_dict.keys() or
            compile_dict['loss_weights'] is None or
            type(compile_dict['loss_weights']) is list or
            type(compile_dict['loss_weights']) is dict,
            "wrong input type for compile parameter loss_weights: only list "
            "and dictionary are supported.")

    _assert('weighted_metrics' not in compile_dict.keys() or
            compile_dict['weighted_metrics'] is None or
            type(compile_dict['weighted_metrics']) is list,
            "wrong input type for compile parameter weighted_metrics: only list "
            "is supported.")

    _assert('sample_weight_mode' not in compile_dict.keys() or
            compile_dict['sample_weight_mode'] is None or
            compile_dict['sample_weight_mode'] == "temporal",
            """compile parameter sample_weight_mode can only be "temporal" or None""")

# Returns an object of custom function name and it corresponding object
def query_custom_functions_map(object_table, custom_fn_names):
    """
    Args:
        @param: object_table    Name of the object table
        @param: custom_fn_names List of custom function read from compile_param
                                if custom function exist in compile_params,
                                    expected list length >= 1
                                else,
                                    an empty list is passed in
    Returns:
        custom_fn_map_obj:      A dill object of a dictionary mapping custom function
                                name to its definition object as read from the object
                                table
                                Example:
                                {custom_fn1 : function_def_obj1, custom_fn2 : function_def_obj2}

    """
    # Dictionary map of name:object
    # {custom_fn1 : function_def_obj1, custom_fn2 : function_def_obj2}
    custom_fn_map = dict()

    if len(custom_fn_names) < 1:
        return custom_fn_map

    fn_set = set(custom_fn_names)
    unique_fn_list = list(fn_set)

    custom_obj_col_name = CustomFunctionSchema.FN_OBJ
    # Query the custom function if not yet loaded from table
    res = plpy.execute("""
                        SELECT {custom_fn_col_name}, {custom_obj_col_name} FROM {object_table}
                        WHERE {custom_fn_col_name} = ANY(ARRAY{unique_fn_list})
                       """.format(custom_obj_col_name=custom_obj_col_name,
                                  object_table=object_table,
                                  custom_fn_col_name=CustomFunctionSchema.FN_NAME,
                                  unique_fn_list=unique_fn_list))
    if res.nrows() < len(unique_fn_list):
        plpy.error("Custom function {0} not defined in object table '{1}'".format(unique_fn_list, object_table))
    for r in res:
        custom_fn_map[r[CustomFunctionSchema.FN_NAME]] = dill.loads(r[custom_obj_col_name])
    custom_fn_map_obj = dill.dumps(custom_fn_map)
    return custom_fn_map_obj

def get_custom_functions_list(compile_params):
    """
    Args:
        @param: compile_params  compile params passed to keras.compile
    Returns:
        custom_fn_list:         List of custom function read from compile_param
                                if custom function exist in compile_params,
                                    returns list length >= 1
                                else,
                                    returns an empty list
                                Example:
                                if custom function exist in compile_params,
                                    returns [custom_fn1, custom_fn2, ....]
                                else,
                                    []

    """
    compile_dict = convert_string_of_args_to_dict(compile_params)
    builtin_losses = dir(losses)
    builtin_metrics = update_builtin_metrics(dir(metrics))

    custom_fn_list = []
    local_loss = compile_dict['loss'].lower() if 'loss' in compile_dict else None
    local_metric = compile_dict['metrics'].lower()[2:-2] if 'metrics' in compile_dict else None
    if local_loss and (local_loss not in [a.lower() for a in builtin_losses]):
        custom_fn_list.append(local_loss)
    if local_metric and (local_metric not in [a.lower() for a in builtin_metrics]):
        if 'top_k_categorical_accuracy' not in local_metric:
            custom_fn_list.append(local_metric)

    return custom_fn_list
