/*
  Copyright (C) 2009-2018  Brazil
  Copyright (C) 2019-2026  Sutou Kouhei <kou@clear-code.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#pragma once

#include "grn.h"

#ifdef __cplusplus
extern "C" {
#endif

#define GRN_SELECT_DEFAULT_LIMIT                       10
#define GRN_SELECT_DEFAULT_OUTPUT_COLUMNS_FOR_NO_KEY   "_id, *"
#define GRN_SELECT_DEFAULT_OUTPUT_COLUMNS_FOR_WITH_KEY "_id, _key, *"

void
grn_proc_init_from_env(void);
void
grn_proc_query_init_from_env(void);

GRN_VAR const char *grn_document_root;
void
grn_db_init_builtin_commands(grn_ctx *ctx);

void
grn_proc_init_cast_loose(grn_ctx *ctx);
void
grn_proc_init_clearlock(grn_ctx *ctx);
void
grn_proc_init_column_copy(grn_ctx *ctx);
void
grn_proc_init_column_create(grn_ctx *ctx);
void
grn_proc_init_column_create_similar(grn_ctx *ctx);
void
grn_proc_init_column_list(grn_ctx *ctx);
void
grn_proc_init_column_remove(grn_ctx *ctx);
void
grn_proc_init_column_rename(grn_ctx *ctx);
void
grn_proc_init_command_list(grn_ctx *ctx);
void
grn_proc_init_config_get(grn_ctx *ctx);
void
grn_proc_init_config_set(grn_ctx *ctx);
void
grn_proc_init_config_delete(grn_ctx *ctx);
void
grn_proc_init_define_selector(grn_ctx *ctx);
void
grn_proc_init_distance_cosine(grn_ctx *ctx);
void
grn_proc_init_distance_inner_product(grn_ctx *ctx);
void
grn_proc_init_distance_l1_norm(grn_ctx *ctx);
void
grn_proc_init_distance_l2_norm_squared(grn_ctx *ctx);
void
grn_proc_init_dump(grn_ctx *ctx);
void
grn_proc_init_edit_distance(grn_ctx *ctx);
void
grn_proc_init_escalate(grn_ctx *ctx);
void
grn_proc_init_extract(grn_ctx *ctx);
void
grn_proc_init_fuzzy_search(grn_ctx *ctx);
void
grn_proc_init_highlight(grn_ctx *ctx);
void
grn_proc_init_highlight_full(grn_ctx *ctx);
void
grn_proc_init_highlight_html(grn_ctx *ctx);
void
grn_proc_init_in_records(grn_ctx *ctx);
void
grn_proc_init_index_column_diff(grn_ctx *ctx);
void
grn_proc_init_json_extract(grn_ctx *ctx);
void
grn_proc_init_lock_acquire(grn_ctx *ctx);
void
grn_proc_init_lock_clear(grn_ctx *ctx);
void
grn_proc_init_lock_release(grn_ctx *ctx);
void
grn_proc_init_log_level(grn_ctx *ctx);
void
grn_proc_init_log_put(grn_ctx *ctx);
void
grn_proc_init_log_reopen(grn_ctx *ctx);
void
grn_proc_init_normalize(grn_ctx *ctx);
void
grn_proc_init_object_exist(grn_ctx *ctx);
void
grn_proc_init_object_inspect(grn_ctx *ctx);
void
grn_proc_init_object_list(grn_ctx *ctx);
void
grn_proc_init_object_remove(grn_ctx *ctx);
void
grn_proc_init_object_set_visibility(grn_ctx *ctx);
void
grn_proc_init_object_warm(grn_ctx *ctx);
void
grn_proc_init_query(grn_ctx *ctx);
void
grn_proc_init_query_parallel_or(grn_ctx *ctx);
void
grn_proc_init_query_expand(grn_ctx *ctx);
void
grn_proc_init_query_log_flags_get(grn_ctx *ctx);
void
grn_proc_init_query_log_flags_set(grn_ctx *ctx);
void
grn_proc_init_query_log_flags_add(grn_ctx *ctx);
void
grn_proc_init_query_log_flags_remove(grn_ctx *ctx);
void
grn_proc_init_reference_acquire(grn_ctx *ctx);
void
grn_proc_init_reference_release(grn_ctx *ctx);
void
grn_proc_init_schema(grn_ctx *ctx);
void
grn_proc_init_select(grn_ctx *ctx);
void
grn_proc_init_sleep(grn_ctx *ctx);
void
grn_proc_init_snippet(grn_ctx *ctx);
void
grn_proc_init_snippet_html(grn_ctx *ctx);
void
grn_proc_init_table_copy(grn_ctx *ctx);
void
grn_proc_init_table_create(grn_ctx *ctx);
void
grn_proc_init_table_create_similar(grn_ctx *ctx);
void
grn_proc_init_table_list(grn_ctx *ctx);
void
grn_proc_init_table_remove(grn_ctx *ctx);
void
grn_proc_init_table_rename(grn_ctx *ctx);
void
grn_proc_init_table_tokenize(grn_ctx *ctx);
void
grn_proc_init_thread_dump(grn_ctx *ctx);
void
grn_proc_init_thread_limit(grn_ctx *ctx);
void
grn_proc_init_tokenize(grn_ctx *ctx);

bool
grn_proc_option_value_bool(grn_ctx *ctx, grn_obj *option, bool default_value);
int32_t
grn_proc_option_value_int32(grn_ctx *ctx,
                            grn_obj *option,
                            int32_t default_value);
uint32_t
grn_proc_option_value_uint32(grn_ctx *ctx,
                             grn_obj *option,
                             uint32_t default_value);
float
grn_proc_option_value_float(grn_ctx *ctx, grn_obj *option, float default_value);
double
grn_proc_option_value_double(grn_ctx *ctx,
                             grn_obj *option,
                             double default_value);
const char *
grn_proc_option_value_string(grn_ctx *ctx, grn_obj *option, size_t *size);
grn_content_type
grn_proc_option_value_content_type(grn_ctx *ctx,
                                   grn_obj *option,
                                   grn_content_type default_value);
grn_log_level
grn_proc_option_value_log_level(grn_ctx *ctx,
                                grn_obj *option,
                                grn_log_level default_value);
bool
grn_proc_get_value_bool(grn_ctx *ctx,
                        grn_obj *value,
                        bool default_value,
                        const char *tag);
int32_t
grn_proc_get_value_int32(grn_ctx *ctx,
                         grn_obj *value,
                         int32_t default_value_raw,
                         const char *tag);
uint32_t
grn_proc_get_value_uint32(grn_ctx *ctx,
                          grn_obj *value,
                          uint32_t default_value_raw,
                          const char *tag);
int64_t
grn_proc_get_value_int64(grn_ctx *ctx,
                         grn_obj *value,
                         int64_t default_value_raw,
                         const char *tag);
grn_operator
grn_proc_get_value_mode(grn_ctx *ctx,
                        grn_obj *value,
                        grn_operator default_mode,
                        const char *tag);
grn_operator
grn_proc_get_value_operator(grn_ctx *ctx,
                            grn_obj *value,
                            grn_operator default_operator,
                            const char *tag);
grn_tokenize_mode
grn_proc_get_value_tokenize_mode(grn_ctx *ctx,
                                 grn_obj *value,
                                 grn_tokenize_mode default_mode,
                                 const char *tag);
uint32_t
grn_proc_get_value_token_cursor_flags(grn_ctx *ctx,
                                      grn_obj *value,
                                      uint32_t default_flags,
                                      const char *tag);
double
grn_proc_get_value_double(grn_ctx *ctx,
                          grn_obj *value,
                          double default_value_raw,
                          const char *tag);
grn_obj *
grn_proc_get_value_object(grn_ctx *ctx, grn_obj *value, const char *tag);
grn_obj *
grn_proc_get_value_column(grn_ctx *ctx,
                          grn_obj *value,
                          grn_obj *table,
                          const char *tag);
grn_raw_string
grn_proc_get_value_raw_string(grn_ctx *ctx,
                              grn_obj *value,
                              grn_raw_string *default_value,
                              const char *tag);

void
grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj);
void
grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id);

bool
grn_proc_table_set_token_filters(grn_ctx *ctx,
                                 grn_obj *table,
                                 grn_raw_string *token_filters_raw);
bool
grn_proc_table_set_extractors(grn_ctx *ctx,
                              grn_obj *table,
                              grn_raw_string *extractors_raw);

grn_column_flags
grn_proc_column_parse_flags(grn_ctx *ctx,
                            const char *error_message_tag,
                            const char *text,
                            const char *end);

bool
grn_proc_select_output_columns_open(grn_ctx *ctx,
                                    grn_obj_format *format,
                                    grn_obj *result_set,
                                    int n_hits,
                                    int offset,
                                    int limit,
                                    const char *columns,
                                    unsigned int columns_len,
                                    grn_obj *condition,
                                    uint32_t n_additional_elements);
bool
grn_proc_select_output_columns_close(grn_ctx *ctx,
                                     grn_obj_format *format,
                                     grn_obj *result_set);
bool
grn_proc_select_output_columns(grn_ctx *ctx,
                               grn_obj *res,
                               int n_hits,
                               int offset,
                               int limit,
                               const char *columns,
                               unsigned int columns_len,
                               grn_obj *condition);

grn_rc
grn_proc_syntax_expand_query(grn_ctx *ctx,
                             const char *query,
                             unsigned int query_len,
                             grn_expr_flags flags,
                             grn_obj *query_expander,
                             const char *term_column_name,
                             unsigned int term_column_name_len,
                             const char *expanded_term_column_name,
                             unsigned int expanded_term_column_name_len,
                             grn_obj *expanded_query,
                             const char *error_message_tag);

grn_expr_flags
grn_proc_expr_query_flags_parse(grn_ctx *ctx,
                                grn_obj *query_flags,
                                const char *error_message_tag);

grn_obj *
grn_proc_lexicon_open(grn_ctx *ctx,
                      grn_raw_string *tokenizer_raw,
                      grn_raw_string *normalizer_raw,
                      grn_raw_string *token_filters_raw,
                      grn_raw_string *extractors_raw,
                      const char *context_tag);

bool
grn_proc_text_include_special_character(grn_ctx *ctx,
                                        const char *text,
                                        size_t size);

typedef struct {
  grn_obj *found;
  grn_obj *table;
  grn_obj *records;
} grn_proc_selector_to_function_data;

bool
grn_proc_selector_to_function_data_init(
  grn_ctx *ctx,
  grn_proc_selector_to_function_data *data,
  grn_user_data *user_data);
void
grn_proc_selector_to_function_data_selected(
  grn_ctx *ctx, grn_proc_selector_to_function_data *data);
void
grn_proc_selector_to_function_data_fin(
  grn_ctx *ctx, grn_proc_selector_to_function_data *data);

#ifdef __cplusplus
}
#endif
