# 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 plpy
from input_data_preprocessor import DistributionRulesOptions
from keras_model_arch_table import ModelArchSchema
from model_arch_info import get_num_classes
from madlib_keras_custom_function import CustomFunctionSchema
from madlib_keras_helper import CLASS_VALUES_COLNAME
from madlib_keras_helper import COMPILE_PARAMS_COLNAME
from madlib_keras_helper import DEPENDENT_VARNAME_COLNAME
from madlib_keras_helper import DEPENDENT_VARTYPE_COLNAME
from madlib_keras_helper import MODEL_ID_COLNAME
from madlib_keras_helper import MODEL_ARCH_TABLE_COLNAME
from madlib_keras_helper import MODEL_WEIGHTS_COLNAME
from madlib_keras_helper import NORMALIZING_CONST_COLNAME
from madlib_keras_helper import DISTRIBUTION_KEY_COLNAME
from madlib_keras_helper import METRIC_TYPE_COLNAME
from madlib_keras_helper import INTERNAL_GPU_CONFIG
from madlib_keras_helper import query_model_configs

from utilities.minibatch_validation import validate_bytea_var_for_minibatch
from utilities.utilities import _assert
from utilities.utilities import add_postfix
from utilities.utilities import is_platform_pg
from utilities.utilities import is_var_valid
from utilities.validate_args import cols_in_tbl_valid
from utilities.validate_args import columns_exist_in_table
from utilities.validate_args import get_expr_type
from utilities.validate_args import input_tbl_valid
from utilities.validate_args import output_tbl_valid
from madlib_keras_wrapper import parse_and_validate_fit_params
from madlib_keras_wrapper import parse_and_validate_compile_params
import keras.losses as losses
import keras.metrics as metrics

class InputValidator:
    @staticmethod
    def validate_predict_evaluate_tables(
        module_name, model_table, model_summary_table, test_table, output_table,
        independent_varname):
        InputValidator._validate_model_weights_tbl(module_name, model_table)
        InputValidator._validate_model_summary_tbl(
            module_name, model_summary_table)
        InputValidator._validate_test_tbl(
            module_name, test_table, independent_varname)
        output_tbl_valid(output_table, module_name)

    @staticmethod
    def validate_id_in_test_tbl(module_name, test_table, id_col):
        _assert(is_var_valid(test_table, id_col),
                "{module_name} error: invalid id column "
                "('{id_col}') for test table ({table}).".format(
                    module_name=module_name,
                    id_col=id_col,
                    table=test_table))

    @staticmethod
    def validate_predict_byom_tables(module_name, model_arch_table, model_id,
                                     test_table, id_col, output_table,
                                     independent_varname):
        InputValidator.validate_model_arch_table(
            module_name, model_arch_table, model_id)
        InputValidator._validate_test_tbl(
            module_name, test_table, independent_varname)
        InputValidator.validate_id_in_test_tbl(module_name, test_table, id_col)

        output_tbl_valid(output_table, module_name)


    @staticmethod
    def validate_pred_type(module_name, pred_type, class_values):

        error = False
        if type(pred_type) == str:
            if not pred_type in ['prob', 'response']:
                error = True
        elif type(pred_type) == int:
            if pred_type <= 0:
                error = True
        else:
            if pred_type < 0.0 or pred_type >= 1.0:
                error = True
        if error:
            plpy.error("{0}: Invalid value for pred_type param ({1}). "\
                "Must be integer>0, double precision in the range [0.0,1.0), "\
                "'response' or 'prob'.".format(module_name, pred_type))

    @staticmethod
    def validate_input_shape(table, independent_varname, input_shape, offset,
                             is_minibatched=False):
        """
        Validate if the input shape specified in model architecture is the same
        as the shape of the image specified in the indepedent var of the input
        table.
        offset: This offset is the index of the start of the image array. We also
        need to consider that sql array indexes start from 1
        For ex if the image is of shape [32,32,3] and is minibatched, the image will
        look like [10, 32, 32, 3]. The offset in this case is 1 (start the index at 1) +
        1 (ignore the buffer size 10) = 2.
        If the image is not batched then it will look like [32, 32 ,3] and the offset in
        this case is 1 (start the index at 1).
        """

        if is_minibatched:
            ind_shape_col = add_postfix(independent_varname, "_shape")
            query = """
                SELECT {ind_shape_col} AS shape
                FROM {table}
                LIMIT 1
            """.format(**locals())
            # This query will fail if an image in independent var does not have the
            # same number of dimensions as the input_shape.
            result = plpy.execute(query)[0]['shape']
            result = result[1:]
        else:
            array_upper_query = ", ".join("array_upper({0}, {1}) AS n_{2}".format(
                independent_varname, i+offset, i) for i in range(len(input_shape)))
            query = """
                SELECT {0}
                FROM {1}
                LIMIT 1
            """.format(array_upper_query, table)

            # This query will fail if an image in independent var does not have the
            # same number of dimensions as the input_shape.
            result = plpy.execute(query)[0]

        _assert(len(result) == len(input_shape),
            "model_keras error: The number of dimensions ({0}) of each image"
            " in model architecture and {1} in {2} ({3}) do not match.".format(
                len(input_shape), independent_varname, table, len(result)))

        for i in range(len(input_shape)):
            if is_minibatched:
                key_name = i
                input_shape_from_table = [result[j]
                    for j in range(len(input_shape))]
            else:
                key_format = "n_{0}"
                key_name = key_format.format(i)
                input_shape_from_table = [result[key_format.format(j)]
                    for j in range(len(input_shape))]

            if result[key_name] != input_shape[i]:
                # Construct the shape in independent varname to display
                # meaningful error msg.
                plpy.error("model_keras error: Input shape {0} in the model"
                    " architecture does not match the input shape {1} of column"
                    " {2} in table {3}.".format(
                        input_shape, input_shape_from_table,
                        independent_varname, table))

    @staticmethod
    def validate_model_arch_table(module_name, model_arch_table, model_id):
        input_tbl_valid(model_arch_table, module_name)
        _assert(model_id is not None,
            "{0}: Invalid model architecture ID.".format(module_name))


    @staticmethod
    def validate_normalizing_const(module_name, normalizing_const):
        _assert(normalizing_const > 0,
                "{0} error: Normalizing constant has to be greater than 0.".
                format(module_name))

    @staticmethod
    def validate_class_values(module_name, class_values, pred_type, model_arch):
        if not class_values:
            return
        num_classes = len(class_values)
        _assert(num_classes == get_num_classes(model_arch),
                "{0}: The number of class values do not match the " \
                "provided architecture.".format(module_name))
        if pred_type == 'prob' and num_classes+1 >= 1600:
            plpy.error({"{0}: The output will have {1} columns, exceeding the "\
                " max number of columns that can be created (1600)".format(
                    module_name, num_classes+1)})

    @staticmethod
    def validate_model_weights(module_name, model_arch, model_weights):
        _assert(model_weights and model_arch,
                "{0}: Model weights and architecture must be valid.".format(
                    module_name))

    @staticmethod
    def _validate_model_weights_tbl(module_name, model_table):
        _assert(is_var_valid(model_table, MODEL_WEIGHTS_COLNAME),
                "{module_name} error: column '{model_weights}' "
                "does not exist in model table '{table}'.".format(
                    module_name=module_name,
                    model_weights=MODEL_WEIGHTS_COLNAME,
                    table=model_table))
        _assert(is_var_valid(model_table, ModelArchSchema.MODEL_ARCH),
                "{module_name} error: column '{model_arch}' "
                "does not exist in model table '{table}'.".format(
                    module_name=module_name,
                    model_arch=ModelArchSchema.MODEL_ARCH,
                    table=model_table))

    @staticmethod
    def _validate_test_tbl(module_name, test_table, independent_varname):
        input_tbl_valid(test_table, module_name)
        _assert(is_var_valid(test_table, independent_varname),
                "{module_name} error: invalid independent_varname "
                "('{independent_varname}') for test table "
                "({table}).".format(
                    module_name=module_name,
                    independent_varname=independent_varname,
                    table=test_table))

    @staticmethod
    def _validate_model_summary_tbl(module_name, model_summary_table):
        input_tbl_valid(model_summary_table, module_name)
        cols_to_check_for = [CLASS_VALUES_COLNAME,
                             DEPENDENT_VARNAME_COLNAME,
                             DEPENDENT_VARTYPE_COLNAME,
                             MODEL_ID_COLNAME,
                             MODEL_ARCH_TABLE_COLNAME,
                             NORMALIZING_CONST_COLNAME,
                             COMPILE_PARAMS_COLNAME,
                             METRIC_TYPE_COLNAME]
        _assert(columns_exist_in_table(
            model_summary_table, cols_to_check_for),
            "{0} error: One or more expected columns missing in model "
            "summary table ('{1}'). The expected columns are {2}.".format(
                module_name, model_summary_table, cols_to_check_for))

    @staticmethod
    def _validate_gpu_config(module_name, source_table, accessible_gpus_for_seg):

        summary_table = add_postfix(source_table, "_summary")
        gpu_config = plpy.execute(
            "SELECT {0} FROM {1}".format(INTERNAL_GPU_CONFIG, summary_table)
            )[0][INTERNAL_GPU_CONFIG]
        if gpu_config == DistributionRulesOptions.ALL_SEGMENTS:
            _assert(0 not in accessible_gpus_for_seg,
                "{0} error: Host(s) are missing gpus.".format(module_name))
        else:
            for i in gpu_config:
                _assert(accessible_gpus_for_seg[i] != 0,
                    "{0} error: Segment {1} does not have gpu".format(module_name, i))

class FitCommonValidator(object):
    def __init__(self, source_table, validation_table, output_model_table,
                 model_arch_table, model_id, dependent_varname,
                 independent_varname, num_iterations,
                 metrics_compute_frequency, warm_start,
                 use_gpus, accessible_gpus_for_seg, module_name, object_table):
        self.source_table = source_table
        self.validation_table = validation_table
        self.output_model_table = output_model_table
        self.model_arch_table = model_arch_table
        self.model_id = model_id
        self.dependent_varname = dependent_varname
        self.independent_varname = independent_varname
        self.dep_shape_col = add_postfix(dependent_varname, "_shape")
        self.ind_shape_col = add_postfix(independent_varname, "_shape")
        self.metrics_compute_frequency = metrics_compute_frequency
        self.warm_start = warm_start
        self.num_iterations = num_iterations
        self.object_table = object_table
        self.source_summary_table = None
        if self.source_table:
            self.source_summary_table = add_postfix(
                self.source_table, "_summary")
        if self.output_model_table:
            self.output_summary_model_table = add_postfix(
                self.output_model_table, "_summary")
        self.accessible_gpus_for_seg = accessible_gpus_for_seg
        self.module_name = module_name
        self._validate_common_args()
        if use_gpus:
            InputValidator._validate_gpu_config(self.module_name,
                self.source_table, self.accessible_gpus_for_seg)

    def _validate_common_args(self):
        _assert(self.num_iterations > 0,
            "{0}: Number of iterations cannot be < 1.".format(self.module_name))
        _assert(self._is_valid_metrics_compute_frequency(),
            "{0}: metrics_compute_frequency must be in the range (1 - {1}).".format(
                self.module_name, self.num_iterations))
        input_tbl_valid(self.source_table, self.module_name)
        if self.object_table is not None:
            input_tbl_valid(self.object_table, self.module_name)
            cols_in_tbl_valid(self.object_table, CustomFunctionSchema.col_names, self.module_name)
        input_tbl_valid(self.source_summary_table, self.module_name,
                        error_suffix_str="Please ensure that the source table ({0}) "
                                         "has been preprocessed by "
                                         "the image preprocessor.".format(self.source_table))
        cols_in_tbl_valid(self.source_summary_table, [CLASS_VALUES_COLNAME,
            NORMALIZING_CONST_COLNAME, DEPENDENT_VARTYPE_COLNAME,
            'dependent_varname', 'independent_varname'], self.module_name)
        if not is_platform_pg():
            cols_in_tbl_valid(self.source_table, [DISTRIBUTION_KEY_COLNAME], self.module_name)

        # Source table and validation tables must have the same schema
        self._validate_input_table(self.source_table)
        validate_bytea_var_for_minibatch(self.source_table,
                                         self.dependent_varname)

        self._validate_validation_table()
        if self.warm_start:
            input_tbl_valid(self.output_model_table, self.module_name)
            input_tbl_valid(self.output_summary_model_table, self.module_name)
        else:
            output_tbl_valid(self.output_model_table, self.module_name)
            output_tbl_valid(self.output_summary_model_table, self.module_name)

    def _validate_input_table(self, table):
        _assert(is_var_valid(table, self.independent_varname),
                "{module_name}: invalid independent_varname "
                "('{independent_varname}') for table ({table}). "
                "Please ensure that the input table ({table}) "
                "has been preprocessed by the image preprocessor.".format(
                    module_name=self.module_name,
                    independent_varname=self.independent_varname,
                    table=table))

        _assert(is_var_valid(table, self.dependent_varname),
                "{module_name}: invalid dependent_varname "
                "('{dependent_varname}') for table ({table}). "
                "Please ensure that the input table ({table}) "
                "has been preprocessed by the image preprocessor.".format(
                    module_name=self.module_name,
                    dependent_varname=self.dependent_varname,
                    table=table))

        _assert(is_var_valid(table, self.ind_shape_col),
                "{module_name}: invalid independent_var_shape "
                "('{ind_shape_col}') for table ({table}). "
                "Please ensure that the input table ({table}) "
                "has been preprocessed by the image preprocessor.".format(
                    module_name=self.module_name,
                    ind_shape_col=self.ind_shape_col,
                    table=table))

        _assert(is_var_valid(table, self.dep_shape_col),
                "{module_name}: invalid dependent_var_shape "
                "('{dep_shape_col}') for table ({table}). "
                "Please ensure that the input table ({table}) "
                "has been preprocessed by the image preprocessor.".format(
                    module_name=self.module_name,
                    dep_shape_col=self.dep_shape_col,
                    table=table))

        if not is_platform_pg():
            _assert(is_var_valid(table, DISTRIBUTION_KEY_COLNAME),
                    "{module_name}: missing distribution key "
                    "('{dist_key_col}') for table ({table}). "
                    "Please ensure that the input table ({table}) "
                    "has been preprocessed by the image preprocessor.".format(
                        module_name=self.module_name,
                        dist_key_col=DISTRIBUTION_KEY_COLNAME,
                        table=table))

    def _is_valid_metrics_compute_frequency(self):
        return self.metrics_compute_frequency is None or \
               (self.metrics_compute_frequency >= 1 and \
               self.metrics_compute_frequency <= self.num_iterations)

    def _validate_validation_table(self):
        if self.validation_table and self.validation_table.strip() != '':
            input_tbl_valid(self.validation_table, self.module_name)
            self._validate_input_table(self.validation_table)
            dependent_vartype = get_expr_type(self.dependent_varname,
                                              self.validation_table)
            _assert(dependent_vartype == 'bytea',
                    "Dependent variable column {0} in validation table {1} should be "
                    "a bytea and also one hot encoded.".format(
                        self.dependent_varname, self.validation_table))


    def validate_input_shapes(self, input_shape):
        InputValidator.validate_input_shape(self.source_table, self.independent_varname,
                               input_shape, 2, True)
        if self.validation_table:
            InputValidator.validate_input_shape(
                self.validation_table, self.independent_varname,
                input_shape, 2, True)


class FitInputValidator(FitCommonValidator):
    def __init__(self, source_table, validation_table, output_model_table,
                 model_arch_table, model_id, dependent_varname,
                 independent_varname, num_iterations,
                 metrics_compute_frequency, warm_start,
                 use_gpus, accessible_gpus_for_seg, object_table):

        self.module_name = 'madlib_keras_fit'
        super(FitInputValidator, self).__init__(source_table,
                                                validation_table,
                                                output_model_table,
                                                model_arch_table,
                                                model_id,
                                                dependent_varname,
                                                independent_varname,
                                                num_iterations,
                                                metrics_compute_frequency,
                                                warm_start,
                                                use_gpus,
                                                accessible_gpus_for_seg,
                                                self.module_name,
                                                object_table)
        InputValidator.validate_model_arch_table(self.module_name, self.model_arch_table,
            self.model_id)

class FitMultipleInputValidator(FitCommonValidator):
    def __init__(self, source_table, validation_table, output_model_table,
                 model_selection_table, model_selection_summary_table, dependent_varname,
                 independent_varname, num_iterations, model_info_table, mst_key_col,
                 model_arch_table_col, metrics_compute_frequency, warm_start,
                 use_gpus, accessible_gpus_for_seg):

        self.module_name = 'madlib_keras_fit_multiple'

        input_tbl_valid(model_selection_table, self.module_name)
        input_tbl_valid(model_selection_summary_table, self.module_name,
                        error_suffix_str="Please ensure that the model selection table ({0}) "
                                         "has been created by "
                                         "load_model_selection_table().".format(
                                            model_selection_table))
        self.msts, self.model_arch_table, self.object_table = query_model_configs(
            model_selection_table, model_selection_summary_table,
            mst_key_col, model_arch_table_col)
        if warm_start:
            input_tbl_valid(model_info_table, self.module_name)
        else:
            output_tbl_valid(model_info_table, self.module_name)
        super(FitMultipleInputValidator, self).__init__(source_table,
                                                        validation_table,
                                                        output_model_table,
                                                        self.model_arch_table,
                                                        None,
                                                        dependent_varname,
                                                        independent_varname,
                                                        num_iterations,
                                                        metrics_compute_frequency,
                                                        warm_start,
                                                        use_gpus,
                                                        accessible_gpus_for_seg,
                                                        self.module_name,
                                                        self.object_table)

class MstLoaderInputValidator():
    def __init__(self,
                 schema_madlib,
                 model_arch_table,
                 model_selection_table,
                 model_selection_summary_table,
                 model_id_list,
                 compile_params_list,
                 fit_params_list,
                 object_table,
                 module_name='load_model_selection_table'
                 ):
        self.schema_madlib = schema_madlib
        self.model_arch_table = model_arch_table
        self.model_selection_table = model_selection_table
        self.model_selection_summary_table = model_selection_summary_table
        self.model_id_list = model_id_list
        self.compile_params_list = compile_params_list
        self.fit_params_list = fit_params_list
        self.object_table = object_table
        self.module_name = module_name #'load_model_selection_table'
        self._validate_input_args()

    def _validate_input_args(self):
        self._validate_input_output_tables()
        self._validate_model_ids()
        if self.module_name == 'load_model_selection_table':
            self._validate_compile_and_fit_params()

    def _validate_model_ids(self):
        model_id_str = '({0})'\
            .format(','.join([str(x) for x in self.model_id_list]))
        query = """
            SELECT count(model_id)
            FROM {self.model_arch_table}
            WHERE model_id IN {model_id_str}
        """.format(**locals())
        res = int(plpy.execute(query)[0]['count'])
        _assert(
            res == len(self.model_id_list),
            "{0}: One or more model_id of {1} not found in table {2}".format(
                self.module_name,
                model_id_str,
                self.model_arch_table
            )
        )
    def _validate_compile_and_fit_params(self):
        if not self.fit_params_list:
            plpy.error("fit_params_list cannot be NULL")
        for fit_params in self.fit_params_list:
            try:
                res = parse_and_validate_fit_params(fit_params)
            except Exception as e:
                plpy.error(
                    """Fit param check failed for: {0} \n
                    {1}
                    """.format(fit_params, str(e)))
        if not self.compile_params_list:
            plpy.error( "compile_params_list cannot be NULL")
        custom_fn_name = []
        ## Initialize builtin loss/metrics functions
        builtin_losses = dir(losses)
        builtin_metrics = dir(metrics)
        # Default metrics, since it is not part of the builtin metrics list
        builtin_metrics.append('accuracy')
        if self.object_table is not None:
            res = plpy.execute("SELECT {0} from {1}".format(CustomFunctionSchema.FN_NAME,
                                                            self.object_table))
            for r in res:
                custom_fn_name.append(r[CustomFunctionSchema.FN_NAME])
        for compile_params in self.compile_params_list:
            try:
                _, _, res = parse_and_validate_compile_params(compile_params)
                # Validating if loss/metrics function called in compile_params
                # is either defined in object table or is a built_in keras
                # loss/metrics function
                error_suffix = "but input object table missing!"
                if self.object_table is not None:
                    error_suffix = "is not defined in object table '{0}'!".format(self.object_table)

                _assert(res['loss'] in custom_fn_name or res['loss'] in builtin_losses,
                        "custom function '{0}' used in compile params "\
                        "{1}".format(res['loss'], error_suffix))
                if 'metrics' in res:
                    _assert((len(set(res['metrics']).intersection(custom_fn_name)) > 0
                            or len(set(res['metrics']).intersection(builtin_metrics)) > 0),
                            "custom function '{0}' used in compile params " \
                            "{1}".format(res['metrics'], error_suffix))

            except Exception as e:
                plpy.error(
                    """Compile param check failed for: {0} \n
                    {1}
                    """.format(compile_params, str(e)))

    def _validate_input_output_tables(self):
        input_tbl_valid(self.model_arch_table, self.module_name)
        if self.object_table is not None:
            input_tbl_valid(self.object_table, self.module_name)
        if self.module_name == 'load_model_selection_table' or self.module_name == 'madlib_keras_automl':
            output_tbl_valid(self.model_selection_table, self.module_name)
            output_tbl_valid(self.model_selection_summary_table, self.module_name)


