# 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

from ast import literal_eval
from collections import OrderedDict
from itertools import product as itertools_product
import keras.losses as losses
import keras.metrics as metrics
from keras_model_arch_table import ModelArchSchema
import numpy as np
import plpy
from copy import deepcopy

from madlib_keras_custom_function import CustomFunctionSchema
from madlib_keras_validator import MstLoaderInputValidator
from madlib_keras_wrapper import convert_string_of_args_to_dict
from madlib_keras_wrapper import parse_and_validate_fit_params
from madlib_keras_wrapper import parse_and_validate_compile_params
from utilities.control import MinWarning
from utilities.utilities import add_postfix, extract_keyvalue_params, _assert, _assert_equal
from utilities.validate_args import table_exists, drop_tables

class ModelSelectionSchema:
    MST_KEY = 'mst_key'
    MODEL_ID = ModelArchSchema.MODEL_ID
    MODEL_ARCH_TABLE = 'model_arch_table'
    OBJECT_TABLE = 'object_table'
    COMPILE_PARAMS = 'compile_params'
    FIT_PARAMS = 'fit_params'
    col_types = ('SERIAL', 'INTEGER', 'VARCHAR', 'VARCHAR')
    GRID_SEARCH='grid'
    RANDOM_SEARCH='random'
    OPTIMIZER_PARAMS_LIST = 'optimizer_params_list'

@MinWarning("warning")
class MstLoader():
    """The utility class for loading a model selection table with model parameters.

    Currently just takes all combinations of input parameters passed. This
    utility validates the inputs.

    Attributes:
        compile_params_list (list): The input list of compile params choices.
        fit_params_list (list): The input list of fit params choices.
        model_id_list (list): The input list of model id choices.
        model_arch_table (str): The name of model architecture table.
        model_selection_table (str): The name of the output mst table.
        msts (list): The list of generated msts.

    """

    def __init__(self,
                 model_arch_table,
                 model_selection_table,
                 model_id_list,
                 compile_params_list,
                 fit_params_list,
                 object_table=None,
                 **kwargs):

        self.model_arch_table = model_arch_table
        self.model_selection_table = model_selection_table
        self.model_selection_summary_table = add_postfix(
            model_selection_table, "_summary")
        self.model_id_list = sorted(list(set(model_id_list)))
        self.object_table = object_table
        MstLoaderInputValidator(
            model_arch_table=self.model_arch_table,
            model_selection_table=self.model_selection_table,
            model_selection_summary_table=self.model_selection_summary_table,
            model_id_list=self.model_id_list,
            compile_params_list=compile_params_list,
            fit_params_list=fit_params_list,
            object_table=object_table
        )
        self.compile_params_list = self.params_preprocessed(
            compile_params_list)
        self.fit_params_list = self.params_preprocessed(fit_params_list)

        self.msts = []

        self.find_combinations()

    def load(self):
        """The entry point for loading the model selection table.
        """
        # All of the side effects happen in this function.
        self.create_mst_table()
        self.create_mst_summary_table()
        self.insert_into_mst_table()

    def params_preprocessed(self, list_strs):
        """Preprocess the input lists. Eliminate white spaces and sort them.

        Args:
            list_strs (list): A list of strings.

        Returns:
            list: The preprocessed list of strings.
        """

        dict_dedup = {}
        for string in list_strs:
            d = convert_string_of_args_to_dict(string)
            hash_tuple = tuple( '{0} = {1}' \
                                .format(x, d[x]) for x in sorted(d.keys()))
            dict_dedup[hash_tuple] = string

        return dict_dedup.values()

    def find_combinations(self):
        """Backtracking helper for generating the combinations.
        """
        param_grid = OrderedDict([
            (ModelSelectionSchema.MODEL_ID, self.model_id_list),
            (ModelSelectionSchema.COMPILE_PARAMS, self.compile_params_list),
            (ModelSelectionSchema.FIT_PARAMS, self.fit_params_list)
        ])

        def find_combinations_helper(msts, p, i):
            param_names = param_grid.keys()
            if i < len(param_names):
                for x in param_grid[param_names[i]]:
                    p[param_names[i]] = x
                    find_combinations_helper(msts, p, i + 1)
            else:
                msts.append(p.copy())
        find_combinations_helper(self.msts, {}, 0)

    def create_mst_table(self):
        """Initialize the output mst table.
        """
        create_query = """
                        CREATE TABLE {self.model_selection_table} (
                            {mst_key} SERIAL,
                            {model_id} INTEGER,
                            {compile_params} VARCHAR,
                            {fit_params} VARCHAR,
                            unique ({model_id}, {compile_params}, {fit_params})
                        );
                       """.format(self=self,
                                  mst_key=ModelSelectionSchema.MST_KEY,
                                  model_id=ModelSelectionSchema.MODEL_ID,
                                  compile_params=ModelSelectionSchema.COMPILE_PARAMS,
                                  fit_params=ModelSelectionSchema.FIT_PARAMS)
        with MinWarning('warning'):
            plpy.execute(create_query)

    def create_mst_summary_table(self):
        """Initialize the output mst table.
        """
        create_query = """
                        CREATE TABLE {self.model_selection_summary_table} (
                            {model_arch_table} VARCHAR,
                            {object_table} VARCHAR
                        );
                       """.format(self=self,
                                  model_arch_table=ModelSelectionSchema.MODEL_ARCH_TABLE,
                                  object_table=ModelSelectionSchema.OBJECT_TABLE)
        with MinWarning('warning'):
            plpy.execute(create_query)

    def insert_into_mst_table(self):
        """Insert every thing in self.msts into the mst table.
        """
        for mst in self.msts:
            model_id = mst[ModelSelectionSchema.MODEL_ID]
            compile_params = mst[ModelSelectionSchema.COMPILE_PARAMS]
            fit_params = mst[ModelSelectionSchema.FIT_PARAMS]
            insert_query = """
                            INSERT INTO
                                {self.model_selection_table}(
                                    {model_id_col},
                                    {compile_params_col},
                                    {fit_params_col}
                                )
                            VALUES (
                                {model_id},
                                $${compile_params}$$,
                                $${fit_params}$$
                            )
                           """.format(model_id_col=ModelSelectionSchema.MODEL_ID,
                                      compile_params_col=ModelSelectionSchema.COMPILE_PARAMS,
                                      fit_params_col=ModelSelectionSchema.FIT_PARAMS,
                                      **locals())
            plpy.execute(insert_query)
        if self.object_table is None:
            object_table = 'NULL::VARCHAR'
        else:
            object_table = '$${0}$$'.format(self.object_table)
        insert_summary_query = """
                        INSERT INTO
                            {self.model_selection_summary_table}(
                                {model_arch_table_name},
                                {object_table_name}
                        )
                        VALUES (
                            $${self.model_arch_table}$$,
                            {object_table}
                        )
                       """.format(model_arch_table_name=ModelSelectionSchema.MODEL_ARCH_TABLE,
                                  object_table_name=ModelSelectionSchema.OBJECT_TABLE,
                                  **locals())
        plpy.execute(insert_summary_query)

@MinWarning("warning")
class MstSearch():
    """
    The utility class for generating model selection configs and loading into a MST table with model parameters.

    Currently takes string representations of python dictionaries for compile and fit params.
    Generates configs with a chosen search algorithm

    Attributes:
        model_arch_table (str): The name of model architecture table.
        model_selection_table (str): The name of the output mst table.
        model_id_list (list): The input list of model id choices.
        compile_params_grid (string repr of python dict): The input of compile params choices.
        fit_params_grid (string repr of python dict): The input of fit params choices.
        search_type (str, default 'grid'): Hyperparameter search strategy, 'grid' or 'random'.

        Only for 'random' search type (defaults None):
            num_configs (int): Number of configs to generate.
            random_state (int): Seed for result reproducibility.

        object_table (str, default None): The name of the object table, for custom (metric) functions.

    """

    def __init__(self,
                 model_arch_table,
                 model_selection_table,
                 model_id_list,
                 compile_params_grid,
                 fit_params_grid,
                 search_type='grid',
                 num_configs=None,
                 random_state=None,
                 object_table=None,
                 **kwargs):

        self.model_arch_table = model_arch_table
        self.model_selection_table = model_selection_table
        self.model_selection_summary_table = add_postfix(
            model_selection_table, "_summary")
        self.model_id_list = sorted(list(set(model_id_list)))

        MstLoaderInputValidator(
            model_arch_table=self.model_arch_table,
            model_selection_table=self.model_selection_table,
            model_selection_summary_table=self.model_selection_summary_table,
            model_id_list=self.model_id_list,
            compile_params_list=compile_params_grid,
            fit_params_list=fit_params_grid,
            object_table=object_table,
            module_name='generate_model_configs'
        )

        self.search_type = search_type
        self.num_configs = num_configs
        self.random_state = random_state
        self.object_table = object_table

        compile_params_grid = compile_params_grid.replace('\n', '').replace(' ', '')
        fit_params_grid = fit_params_grid.replace('\n', '').replace(' ', '')
        self.accepted_distributions = ['linear', 'log', 'log_near_one']

        # extracting python dict
        try:
            self.compile_params_dict = literal_eval(compile_params_grid)
        except:
            plpy.error("Invalid syntax in 'compile_params_dict'")
        try:
            self.fit_params_dict = literal_eval(fit_params_grid)
        except:
            plpy.error("Invalid syntax in 'fit_params_dict'")
        self.validate_inputs(compile_params_grid, fit_params_grid)

        self.msts = []

        if ModelSelectionSchema.GRID_SEARCH.startswith(self.search_type.lower()):
            self.find_grid_combinations()
        elif ModelSelectionSchema.RANDOM_SEARCH.startswith(self.search_type.lower()):
            # else should also suffice as random search is established.
            self.find_random_combinations()

        # param checks and validation
        compile_params_lst, fit_params_lst = [], []
        for i in self.msts:
            compile_params_lst.append(i[ModelSelectionSchema.COMPILE_PARAMS])
            fit_params_lst.append(i[ModelSelectionSchema.FIT_PARAMS])
        self._validate_params_and_object_table(compile_params_lst, fit_params_lst)

    def load(self):
        """The entry point for loading the model selection table.
        """
        # All of the side effects happen in this function.
        if table_exists(self.model_selection_table):
            if table_exists(self.model_selection_summary_table):
                res = plpy.execute("SELECT model_arch_table from {0}".format(self.model_selection_summary_table))
                # exactly one value
                for r in res:
                    _assert_equal(r['model_arch_table'], self.model_arch_table,
                            "DL: Inconsistent model arch table. Use '{0}' if appending rows to '{1}'".format(
                                r['model_arch_table'], self.model_selection_table
                            ))
            else:
                self.create_mst_summary_table()
        else:
            self.create_mst_table()
            self.create_mst_summary_table()
        self.insert_into_mst_table()

    def validate_inputs(self, compile_params_grid, fit_params_grid):
        """
        Ensures validity of inputs related to grid and random search.

        :param compile_params_grid: The input string repr of compile params choices.
        :param fit_params_grid: The input string repr of fit params choices.
        """

        for c in self.compile_params_dict:
            _assert_equal(type(self.compile_params_dict[c]), list, "DL: compile param values must be specified in a list")
        for f in self.fit_params_dict:
            _assert_equal(type(self.fit_params_dict[f]), list, "DL: fit param values must be specified in a list")

        if ModelSelectionSchema.GRID_SEARCH.startswith(self.search_type.lower()):
            _assert(self.num_configs is None and self.random_state is None,
                    "DL: 'num_configs' and 'random_state' must be NULL for grid search")
            for distribution_type in self.accepted_distributions:
                _assert(distribution_type not in compile_params_grid and distribution_type not in fit_params_grid,
                        "DL: Cannot search from a distribution with grid search")
        elif ModelSelectionSchema.RANDOM_SEARCH.startswith(self.search_type.lower()):
            _assert(self.num_configs is not None and self.num_configs > 0, "DL: 'num_configs' cannot be NULL and "
                                                                           "needs to be a natural number "
                                                                           "for random search")
        else:
            plpy.error("DL: 'search_type' must be either 'grid' or 'random'")

        if ModelSelectionSchema.OPTIMIZER_PARAMS_LIST in self.compile_params_dict:
            optimizer_params_list = self.compile_params_dict[ModelSelectionSchema.OPTIMIZER_PARAMS_LIST]
            optimizer_param_keys = set([j for i in optimizer_params_list for j in i])
            _assert(set(self.compile_params_dict).isdisjoint(optimizer_param_keys),
                    "DL: 'optimizer_params_list' key should only contain 'optimizer' and/or optimizer related params \
                    and no such params should reside out of the key")
            for k in optimizer_params_list:
                _assert(len(k) != 0, "DL: empty dictionaries cannot be specified in the value list of \
                'optimizer_params_list'")

    def _validate_params_and_object_table(self, compile_params_lst, fit_params_lst):
        if not fit_params_lst:
            plpy.error("fit_params_list cannot be NULL")
        for fit_params in fit_params_lst:
            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 compile_params_lst:
            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 compile_params_lst:
            try:
                _, _, res = parse_and_validate_compile_params(compile_params,
                                                              [ModelSelectionSchema.OPTIMIZER_PARAMS_LIST])
                # 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 find_grid_combinations(self):
        """
        Finds combinations using grid search.
        """
        # assuming optimizer_params_list is present
        if ModelSelectionSchema.OPTIMIZER_PARAMS_LIST in self.compile_params_dict:
            for opt_params_dict in self.compile_params_dict[ModelSelectionSchema.OPTIMIZER_PARAMS_LIST]:
                keys, values = zip(*opt_params_dict.items())
                opt_configs_params = [dict(zip(keys, v)) for v in itertools_product(*values)]
                copied_compile_dict = deepcopy(self.compile_params_dict)
                copied_compile_dict[ModelSelectionSchema.OPTIMIZER_PARAMS_LIST] = opt_configs_params
                self.grid_combinations_helper(copied_compile_dict, self.fit_params_dict)
        else:
            self.grid_combinations_helper(self.compile_params_dict, self.fit_params_dict)

    def grid_combinations_helper(self, compile_dict, fit_dict):
        combined_dict = dict(compile_dict, **fit_dict)
        combined_dict[ModelSelectionSchema.MODEL_ID] = self.model_id_list
        keys, values = zip(*combined_dict.items())
        all_configs_params = [dict(zip(keys, v)) for v in itertools_product(*values)]

        # to separate the compile and fit configs
        for config in all_configs_params:
            combination = {}
            compile_configs, fit_configs = {}, {}
            for k in config:
                if k == ModelSelectionSchema.MODEL_ID:
                    combination[ModelSelectionSchema.MODEL_ID] = config[k]
                elif k in compile_dict:
                    compile_configs[k] = config[k]
                elif k in fit_dict:
                    fit_configs[k] = config[k]
                else:
                    plpy.error("DL: {0} is an unidentified key".format(k))
            combination[ModelSelectionSchema.COMPILE_PARAMS] = self.generate_row_string(compile_configs)
            combination[ModelSelectionSchema.FIT_PARAMS] = self.generate_row_string(fit_configs)
            self.msts.append(combination)

    def find_random_combinations(self):
        """
        Finds combinations using random search.
        """
        seed_changes = 0

        for _ in range(self.num_configs):
            combination = {}
            if self.random_state:
                np.random.seed(self.random_state+seed_changes)
                seed_changes += 1
            combination[ModelSelectionSchema.MODEL_ID] = np.random.choice(self.model_id_list)
            compile_dict, seed_changes = self.generate_param_config(self.compile_params_dict, seed_changes)
            combination[ModelSelectionSchema.COMPILE_PARAMS] = self.generate_row_string(compile_dict)
            fit_dict, seed_changes = self.generate_param_config(self.fit_params_dict, seed_changes)
            combination[ModelSelectionSchema.FIT_PARAMS] = self.generate_row_string(fit_dict)
            self.msts.append(combination)

    def generate_param_config(self, params_dict, seed_changes):
        """
        Generating a parameter configuration for random search.
        :param params_dict: Dictionary of params choices.
        :param config_dict: Dictionary to store param config.
        :param seed_changes: Changes in seed for random sampling + reproducibility.
        :return: config_dict, seed_changes.
        """
        config_dict = {}
        for cp in params_dict:
            if self.random_state:
                np.random.seed(self.random_state+seed_changes)
                seed_changes += 1
            param_values = params_dict[cp]
            if cp == ModelSelectionSchema.OPTIMIZER_PARAMS_LIST:
                opt_dict = np.random.choice(param_values)
                opt_combination = {}
                for i in opt_dict:
                    opt_values = opt_dict[i]
                    if self.random_state:
                        np.random.seed(self.random_state+seed_changes)
                        seed_changes += 1
                    opt_combination[i] = self.sample_val(i, opt_values)
                config_dict[cp] = opt_combination
            else:
                config_dict[cp] = self.sample_val(cp, param_values)
        return config_dict, seed_changes

    def sample_val(self, cp, param_value_list):
        """
        Samples a value from a given list of values, either randomly from a list of discrete elements,
        or from a specified distribution.
        :param cp: compile param
        :param param_value_list: list of values (or specified distribution) for a param
        :return: sampled value
        """
        # check if need to sample from a distribution
        if type(param_value_list[-1]) == str and all([type(i) != str and not callable(i) for i in param_value_list[:-1]]) \
                and len(param_value_list) > 1:
            _assert_equal(len(param_value_list), 3,
                          "DL: '{0}' should have exactly 3 elements if picking from a distribution".format(cp))
            _assert(param_value_list[1] > param_value_list[0],
                    "DL: '{0}' should be of the format [lower_bound, upper_bound, distribution_type]".format(cp))
            if param_value_list[-1] == 'linear':
                return np.random.uniform(param_value_list[0], param_value_list[1])
            elif param_value_list[-1] == 'log':
                return np.power(10, np.random.uniform(np.log10(param_value_list[0]),
                                                      np.log10(param_value_list[1])))
            elif param_value_list[-1] == 'log_near_one':
                return 1.0 - np.power(10, np.random.uniform(np.log10(1.0-param_value_list[1]),
                                                            np.log10(1.0-param_value_list[0])))
            else:
                plpy.error("DL: Please choose a valid distribution type for '{0}': {1}".format(
                    cp, self.accepted_distributions))
        else:
            # random sampling
            return np.random.choice(param_value_list)

    def generate_row_string(self, configs_dict):
        """
        Generate row strings for MST table.
        :param configs_dict: Dictionary of params config.
        :return: string to insert as a row in MST table.
        """
        result_row_string = ""

        if ModelSelectionSchema.OPTIMIZER_PARAMS_LIST in configs_dict:
            optimizer_params_dict = configs_dict[ModelSelectionSchema.OPTIMIZER_PARAMS_LIST]
            if 'optimizer' in optimizer_params_dict:
                if optimizer_params_dict['optimizer'].lower() == 'sgd':
                    optimizer_value = "SGD"
                elif optimizer_params_dict['optimizer'].lower() == 'rmsprop':
                    optimizer_value = "RMSprop"
                else:
                    optimizer_value = optimizer_params_dict['optimizer'].capitalize()
                opt_string = "optimizer" + "=" + "'" + str(optimizer_value) \
                             + "()" + "'"
            else:
                opt_string = "optimizer='RMSprop()'" # default optimizer
            opt_param_string = ""
            for opt_param in optimizer_params_dict:
                if opt_param == 'optimizer':
                    continue
                opt_param_string += opt_param + '=' + str(optimizer_params_dict[opt_param]) + ','
            if opt_param_string == "":
                result_row_string += opt_string
            else:
                opt_param_string = opt_param_string[:-1] # to exclude the last comma
                part = opt_string.split('(')
                result_row_string += part[0] + '(' + opt_param_string + part[1]

        for c in configs_dict:
            if c == ModelSelectionSchema.OPTIMIZER_PARAMS_LIST:
                continue
            elif c == 'metrics':
                if callable(configs_dict[c]):
                    result_row_string += "," + str(c) + "=" + "[" + str(configs_dict[c]) + "]"
                else:
                    result_row_string += "," + str(c) + "=" + "['" + str(configs_dict[c]) + "']"
            else:
                if type(configs_dict[c]) == str or type(configs_dict[c]) == np.string_:
                    result_row_string += "," + str(c) + "=" + "'" + str(configs_dict[c]) + "'"
                else:
                    # ints, floats, none type, booleans
                    result_row_string += "," + str(c) + "=" + str(configs_dict[c])

        if result_row_string[0] == ',':
            return result_row_string[1:]
        return result_row_string

    def create_mst_table(self):
        """Initialize the output mst table, if it doesn't exist (for incremental loading).
        """

        create_query = """
                        CREATE TABLE {self.model_selection_table} (
                            {mst_key} SERIAL,
                            {model_id} INTEGER,
                            {compile_params} VARCHAR,
                            {fit_params} VARCHAR,
                            unique ({model_id}, {compile_params}, {fit_params})
                        );
                       """.format(self=self,
                                  mst_key=ModelSelectionSchema.MST_KEY,
                                  model_id=ModelSelectionSchema.MODEL_ID,
                                  compile_params=ModelSelectionSchema.COMPILE_PARAMS,
                                  fit_params=ModelSelectionSchema.FIT_PARAMS)
        with MinWarning('warning'):
            plpy.execute(create_query)

    def create_mst_summary_table(self):
        """Initialize the output mst table.
        """
        create_query = """
                        CREATE TABLE {self.model_selection_summary_table} (
                            {model_arch_table} VARCHAR,
                            {object_table} VARCHAR
                        );
                       """.format(self=self,
                                  model_arch_table=ModelSelectionSchema.MODEL_ARCH_TABLE,
                                  object_table=ModelSelectionSchema.OBJECT_TABLE)
        with MinWarning('warning'):
            plpy.execute(create_query)

    def insert_into_mst_table(self):
        """Insert every thing in self.msts into the mst table.
        """
        for mst in self.msts:
            model_id = mst[ModelSelectionSchema.MODEL_ID]
            compile_params = mst[ModelSelectionSchema.COMPILE_PARAMS]
            fit_params = mst[ModelSelectionSchema.FIT_PARAMS]
            insert_query = """
                            INSERT INTO
                                {self.model_selection_table}(
                                    {model_id_col},
                                    {compile_params_col},
                                    {fit_params_col}
                                )
                            VALUES (
                                {model_id},
                                $${compile_params}$$,
                                $${fit_params}$$
                            )
                           """.format(model_id_col=ModelSelectionSchema.MODEL_ID,
                                      compile_params_col=ModelSelectionSchema.COMPILE_PARAMS,
                                      fit_params_col=ModelSelectionSchema.FIT_PARAMS,
                                      **locals())
            plpy.execute(insert_query)
        if self.object_table is None:
            object_table = 'NULL::VARCHAR'
        else:
            object_table = '$${0}$$'.format(self.object_table)
        insert_summary_query = """
                        INSERT INTO
                            {self.model_selection_summary_table}(
                                {model_arch_table_name},
                                {object_table_name}
                        )
                        VALUES (
                            $${self.model_arch_table}$$,
                            {object_table}
                        )
                       """.format(model_arch_table_name=ModelSelectionSchema.MODEL_ARCH_TABLE,
                                  object_table_name=ModelSelectionSchema.OBJECT_TABLE,
                                  **locals())
        plpy.execute(insert_summary_query)
