# 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.utilities import is_superuser
from utilities.utilities import get_table_owner
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
from madlib_keras_custom_function import update_builtin_metrics
from madlib_keras_custom_function import update_builtin_losses
import tensorflow.keras.losses as losses
import tensorflow.keras.metrics as metrics

class InputValidator:
    @staticmethod
    def validate_predict_evaluate_tables(
        module_name, model_table, model_summary_table, test_table, output_table):
        InputValidator._validate_model_weights_tbl(module_name, model_table)
        InputValidator._validate_model_summary_tbl(
            module_name, model_summary_table)
        independent_varname = plpy.execute("SELECT {0} FROM {1}".format(
            "independent_varname", model_summary_table))[0]["independent_varname"]
        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).
        """

        shapes = []
        if is_minibatched:
            for i in independent_varname:
                ind_shape_col = add_postfix(i, "_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)
                result = result[0]['shape']
                shapes.append(result[1:])
        else:
            for counter, ind in enumerate(independent_varname):
                array_upper_query = ", ".join("array_upper({0}, {1})".format(
                    ind, i+offset, i) for i in range(len(input_shape[counter])))
                query = """
                    SELECT ARRAY[{0}] AS shape
                    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)
                result = result[0]['shape']
                shapes.append(result)
        _assert(len(shapes) == 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)):

            local_input_shape = input_shape[i]
            local_arch_shape = shapes[i]

            for j in range(len(local_input_shape)):
                if local_arch_shape[j] != local_input_shape[j]:
                    # 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(
                            local_input_shape[j], local_arch_shape[j],
                            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(i) for i in class_values]
        _assert(num_classes == get_num_classes(model_arch, len(class_values)),
                "{0}: The number of class values do not match the " \
                "provided architecture.".format(module_name))
        for i in num_classes:
            if pred_type == 'prob' and i+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, i+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)
        for i in independent_varname:
            _assert(is_var_valid(test_table, i),
                "{module_name} error: invalid independent_varname "
                "('{i}') for test table "
                "({table}).".format(
                    module_name=module_name,
                    i=i,
                    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 = [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,
                 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.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.validation_table:
            self.validation_summary_table = add_postfix(
                self.validation_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_tables()

        self.src_summary_dict = self.get_source_summary_table_dict(self.source_summary_table)

        self.dependent_varname = self.src_summary_dict['dependent_varname']
        self.independent_varname = self.src_summary_dict['independent_varname']
        if not isinstance(self.dependent_varname, list) or \
                not isinstance(self.independent_varname, list):
            plpy.error("Input table '{0}' was preprocessed with "\
                       "an older version of the input preprocessor. "
                       "Please re-run the current version of input preprocessor "\
                       "on the dataset.".format(self.source_table))
        self.dependent_shape_varname = [add_postfix(i, "_shape") for i in self.dependent_varname]
        self.independent_shape_varname = [add_postfix(i, "_shape") for i in self.independent_varname]

        self.val_dependent_varname = None
        self.val_independent_varname = None
        self.val_dependent_shape_varname = None
        self.val_independent_shape_varname = None
        if self.validation_table:
            val_summary_dict = self.get_source_summary_table_dict(self.validation_summary_table)

            self.val_dependent_varname = val_summary_dict['dependent_varname']
            self.val_independent_varname = val_summary_dict['independent_varname']
            self.val_dependent_shape_varname = [add_postfix(i, "_shape") for i in self.val_dependent_varname]
            self.val_independent_shape_varname = [add_postfix(i, "_shape") for i in self.val_independent_varname]

        self._validate_tables_schema()
        if use_gpus:
            InputValidator._validate_gpu_config(self.module_name,
                self.source_table, self.accessible_gpus_for_seg)

    def _validate_tables(self):
        input_tbl_valid(self.source_table, self.module_name)
        input_tbl_valid(self.source_summary_table, self.module_name)
        if self.validation_table:
            input_tbl_valid(self.validation_table, self.module_name)
            input_tbl_valid(self.validation_summary_table, self.module_name)

        if self.object_table is not None:
            try:
                input_tbl_valid(self.object_table, self.module_name)
            except Exception as e:
                if "Incorrect table name" in e:
                    plpy.error("""Incorrect table name ({0}) provided! """\
                        """Do not include schema name for the object table.
                        """.format(self.object_table))
                else:
                    raise e

            _assert(is_superuser(get_table_owner(self.object_table)),
                "DL: Cannot use a table of a non-superuser as object table.")
            cols_in_tbl_valid(self.object_table, CustomFunctionSchema.col_names, self.module_name)

        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_tables_schema(self):
        # Source table and validation tables must have the same schema
        additional_cols = []
        if not is_platform_pg():
            additional_cols.append(DISTRIBUTION_KEY_COLNAME)

        self._validate_columns_in_preprocessed_table(self.source_table,
                                                     self.independent_varname +
                                                     self.dependent_varname +
                                                     self.independent_shape_varname +
                                                     self.dependent_shape_varname +
                                                     additional_cols)
        for i in self.dependent_varname:
            validate_bytea_var_for_minibatch(self.source_table, i)

        if self.validation_table and self.validation_table.strip() != '':
            self._validate_columns_in_preprocessed_table(self.validation_table,
                                                         self.val_independent_varname +
                                                         self.val_dependent_varname +
                                                         self.val_independent_shape_varname +
                                                         self.val_dependent_shape_varname +
                                                         additional_cols)
            for i in self.val_dependent_varname:
                validate_bytea_var_for_minibatch(self.validation_table, i)

        cols_in_tbl_valid(self.source_summary_table,
                          [NORMALIZING_CONST_COLNAME, DEPENDENT_VARTYPE_COLNAME,
                           'dependent_varname', 'independent_varname'], self.module_name)

    def _validate_misc_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))

    def get_source_summary_table_dict(self, source_summary_table):
        source_summary = plpy.execute("""
                SELECT *
                FROM {0}
            """.format(source_summary_table))[0]
        return source_summary

    def _validate_columns_in_preprocessed_table(self, table_name, col_names):
        for col in col_names:
            _assert(is_var_valid(table_name, col),
                    "{module_name}: invalid column name "
                    "('{col}') for table ({table_name}). "
                    "Please ensure that the input table ({table_name}) "
                    "has been preprocessed.".format(
                        module_name=self.module_name,
                        **locals()))

    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, True)
            validation_summary_table = add_postfix(self.validation_table, "_summary")
            input_tbl_valid(validation_summary_table, self.module_name)
            for i in self.val_dependent_varname:
                dependent_vartype = get_expr_type(i,
                                                  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(
                            i, 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.val_independent_varname,
                input_shape, 2, True)


class FitInputValidator(FitCommonValidator):
    def __init__(self, source_table, validation_table, output_model_table,
                 model_arch_table, model_id, 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,
                                                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, model_arch_table,
            model_id)

class FitMultipleInputValidator(FitCommonValidator):
    def __init__(self, source_table, validation_table, output_model_table,
                 model_selection_table, num_iterations, 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)
        self.model_selection_summary_table = add_postfix(model_selection_table,
                                                         '_summary')
        input_tbl_valid(self.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, self.model_selection_summary_table,
            mst_key_col, model_arch_table_col)
        input_tbl_valid(self.model_arch_table, self.module_name)
        super(FitMultipleInputValidator, self).__init__(source_table,
                                                        validation_table,
                                                        output_model_table,
                                                        num_iterations,
                                                        metrics_compute_frequency,
                                                        warm_start,
                                                        use_gpus,
                                                        accessible_gpus_for_seg,
                                                        self.module_name,
                                                        self.object_table)
        _assert(len(self.dependent_varname) == 1
                or len(self.independent_varname) == 1,
                "Multiple dependent and independent variables not supported "
                "for madlib_keras_fit_multiple_model!")
        self.output_model_info_table = add_postfix(output_model_table, '_info')

        if warm_start:
            input_tbl_valid(self.output_model_info_table, self.module_name)
        else:
            output_tbl_valid(self.output_model_info_table, self.module_name)

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_names = []

        # Initialize builtin loss/metrics functions
        builtin_losses = update_builtin_losses(dir(losses))
        builtin_metrics = update_builtin_metrics(dir(metrics))

        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_names.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_names 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_names)) > 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)
            _assert(is_superuser(get_table_owner(self.object_table)),
                "DL: Cannot use a table of a non-superuser as object table.")
        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)


