# 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
        self.compile_params_dict = literal_eval(compile_params_grid)
        self.fit_params_dict = literal_eval(fit_params_grid)
        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()

        #################
        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.
        """

        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, "DL: 'num_configs' cannot be NULL 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_d = {}
            compile_d, seed_changes = self.generate_param_config(self.compile_params_dict, compile_d, seed_changes)
            combination[ModelSelectionSchema.COMPILE_PARAMS] = self.generate_row_string(compile_d)
            fit_d = {}
            fit_d, seed_changes = self.generate_param_config(self.fit_params_dict, fit_d, seed_changes)
            combination[ModelSelectionSchema.FIT_PARAMS] = self.generate_row_string(fit_d)
            self.msts.append(combination)

    def generate_param_config(self, params_dict, config_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.
        """
        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(cp, 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 param_value_list[-1] in self.accepted_distributions:
            _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 {0}".format(
                    tuple(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)
