# 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

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

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

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

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 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):
    with K.tf.device(device_name):
        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 = K.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)
    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 in optimizers,
            "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 optimizer.__class__ == type and optimizer.__base__ == opt.Optimizer:
            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 exisst 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}

    """
    if len(custom_fn_names) < 1:
        return None

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

    custom_obj_col_name = '{0}'.format(CustomFunctionSchema.FN_OBJ)
    # Dictionary map of name:object
    # {custom_fn1 : function_def_obj1, custom_fn2 : function_def_obj2}
    custom_fn_map = defaultdict(list)
    # 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
