/**
 * 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.
 */

package org.apache.tajo;

import com.google.common.collect.Maps;
import org.apache.tajo.validation.Validator;
import org.apache.tajo.validation.Validators;

import java.util.Map;

import static org.apache.tajo.SessionVars.VariableMode.*;
import static org.apache.tajo.conf.TajoConf.ConfVars;

public enum SessionVars implements ConfigKey {

  // Common Suffix Naming Rules:
  //
  // * LIMIT   - We use the suffix 'LIMIT' if the variable is threshold. So, if some value is greater or less than
  //             the variable with suffix 'LIMIT', some action will be different from before.
  // * SIZE    - The suffix 'SIZE' means a data volume like bytes or mega bytes.
  //             It should be used for user's desired volume.
  // * ENABLED - The suffix 'ENABLED' means a true or false value. If it is true, it will enable some feature.
  //             Otherwise, the feature will be turned off.


  //-------------------------------------------------------------------------------
  // Server Side Only Variables
  //-------------------------------------------------------------------------------
  SESSION_ID(ConfVars.$EMPTY, "session variable", SERVER_SIDE_VAR, String.class, Validators.notNull()),
  SESSION_LAST_ACCESS_TIME(ConfVars.$EMPTY, "last access time", SERVER_SIDE_VAR, Long.class, Validators.min("0")),

  USERNAME(ConfVars.USERNAME, "username", SERVER_SIDE_VAR),
  CLIENT_HOST(ConfVars.$EMPTY, "client hostname", SERVER_SIDE_VAR),

  CURRENT_DATABASE(ConfVars.$EMPTY, "current database", SERVER_SIDE_VAR),

  //-------------------------------------------------------------------------------
  // Client Side Variables
  //-------------------------------------------------------------------------------

  // Client --------------------------------------------------------
  SESSION_EXPIRY_TIME(ConfVars.$CLIENT_SESSION_EXPIRY_TIME, "session expiry time (secs)", DEFAULT,
      Integer.class, Validators.min("0")),

  // Command line interface and its behavior --------------------------------
  CLI_COLUMNS(ConfVars.$CLI_MAX_COLUMN, "Sets the width for the wrapped format", CLI_SIDE_VAR),
  CLI_FORMATTER_CLASS(ConfVars.$CLI_OUTPUT_FORMATTER_CLASS, "Sets the output format class to display results",
      CLI_SIDE_VAR),
  CLI_NULL_CHAR(ConfVars.$CLI_NULL_CHAR, "Sets the string to be printed in place of a null value.", CLI_SIDE_VAR),

  CLI_PAGE_ROWS(ConfVars.$CLI_PRINT_PAUSE_NUM_RECORDS, "Sets the number of rows for paging", CLI_SIDE_VAR),
  CLI_PAGING_ENABLED(ConfVars.$CLI_PRINT_PAUSE, "Enable paging of result display", CLI_SIDE_VAR),
  CLI_DISPLAY_ERROR_TRACE(ConfVars.$CLI_PRINT_ERROR_TRACE, "Enable display of error trace", CLI_SIDE_VAR),

  ON_ERROR_STOP(ConfVars.$CLI_ERROR_STOP, "tsql will exist if an error occurs.", CLI_SIDE_VAR),

  // Timezone & Date ----------------------------------------------------------
  TIMEZONE(ConfVars.$TIMEZONE, "Sets timezone", DEFAULT),
  DATE_ORDER(ConfVars.$DATE_ORDER, "date order (default is YMD)", CLI_SIDE_VAR),

  // Locales and Character set ------------------------------------------------
  // TODO - they are reserved variables, and we should support them.
  LANG(ConfVars.$EMPTY, "Language", FROM_SHELL_ENV),
  LC_ALL(ConfVars.$EMPTY, "String sort order", FROM_SHELL_ENV),
  LC_COLLATE(ConfVars.$EMPTY, "String sort order", FROM_SHELL_ENV),
  LC_CTYPE(ConfVars.$EMPTY, "Character classification (What is a letter? Its upper-case equivalent?)", FROM_SHELL_ENV),
  LC_MESSAGES(ConfVars.$EMPTY, "Language of messages", FROM_SHELL_ENV),
  LC_MONETARY(ConfVars.$EMPTY, "Formatting of currency amounts", FROM_SHELL_ENV),
  LC_NUMERIC(ConfVars.$EMPTY, "Formatting of numbers", FROM_SHELL_ENV),
  LC_TIME(ConfVars.$EMPTY, "Formatting of dates and times", FROM_SHELL_ENV),


  // Query and Optimization ---------------------------------------------------

  // for distributed query strategies
  BROADCAST_NON_CROSS_JOIN_THRESHOLD(ConfVars.$DIST_QUERY_BROADCAST_NON_CROSS_JOIN_THRESHOLD,
      "restriction for the total size of broadcasted table for non-cross join (kb)", DEFAULT, Long.class,
      Validators.min("0")),
  BROADCAST_CROSS_JOIN_THRESHOLD(ConfVars.$DIST_QUERY_BROADCAST_CROSS_JOIN_THRESHOLD,
      "restriction for the total size of broadcasted table for cross join (kb)", DEFAULT, Long.class,
      Validators.min("0")),

  JOIN_TASK_INPUT_SIZE(ConfVars.$DIST_QUERY_JOIN_TASK_VOLUME, "join task input size (mb) ", DEFAULT,
      Integer.class, Validators.min("1")),
  SORT_TASK_INPUT_SIZE(ConfVars.$DIST_QUERY_SORT_TASK_VOLUME, "sort task input size (mb)", DEFAULT,
      Integer.class, Validators.min("1")),
  GROUPBY_TASK_INPUT_SIZE(ConfVars.$DIST_QUERY_GROUPBY_TASK_VOLUME, "group by task input size (mb)", DEFAULT),

  JOIN_PER_SHUFFLE_SIZE(ConfVars.$DIST_QUERY_JOIN_PARTITION_VOLUME, "shuffle output size for join (mb)", DEFAULT,
      Integer.class, Validators.min("1")),
  GROUPBY_PER_SHUFFLE_SIZE(ConfVars.$DIST_QUERY_GROUPBY_PARTITION_VOLUME, "shuffle output size for sort (mb)", DEFAULT,
      Integer.class, Validators.min("1")),
  TABLE_PARTITION_PER_SHUFFLE_SIZE(ConfVars.$DIST_QUERY_TABLE_PARTITION_VOLUME,
      "shuffle output size for partition table write (mb)", DEFAULT, Integer.class, Validators.min("1")),

  GROUPBY_MULTI_LEVEL_ENABLED(ConfVars.$GROUPBY_MULTI_LEVEL_ENABLED, "Multiple level groupby enabled", DEFAULT,
      Boolean.class, Validators.bool()),

  QUERY_EXECUTE_PARALLEL(ConfVars.$QUERY_EXECUTE_PARALLEL_MAX, "Maximum parallel running of execution blocks for a query",
      DEFAULT, Integer.class, Validators.min("1")),

  // for physical Executors
  EXTSORT_BUFFER_SIZE(ConfVars.$EXECUTOR_EXTERNAL_SORT_BUFFER_SIZE, "sort buffer size for external sort (mb)", DEFAULT,
      Long.class, Validators.min("0")),
  HASH_JOIN_SIZE_LIMIT(ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD, "limited size for hash join (mb)", DEFAULT,
      Long.class, Validators.min("0")),
  INNER_HASH_JOIN_SIZE_LIMIT(ConfVars.$EXECUTOR_INNER_HASH_JOIN_SIZE_THRESHOLD,
      "limited size for hash inner join (mb)", DEFAULT, Long.class, Validators.min("0")),
  OUTER_HASH_JOIN_SIZE_LIMIT(ConfVars.$EXECUTOR_OUTER_HASH_JOIN_SIZE_THRESHOLD, "limited size for hash outer join (mb)",
      DEFAULT, Long.class, Validators.min("0")),
  HASH_GROUPBY_SIZE_LIMIT(ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD, "limited size for hash groupby (mb)",
      DEFAULT, Long.class, Validators.min("0")),
  MAX_OUTPUT_FILE_SIZE(ConfVars.$MAX_OUTPUT_FILE_SIZE, "Maximum per-output file size (mb). 0 means infinite.", DEFAULT,
      Long.class, Validators.min("0")),
  NULL_CHAR(ConfVars.$TEXT_NULL, "null char of text file output", DEFAULT),
  CODEGEN(ConfVars.$CODEGEN, "Runtime code generation enabled (experiment)", DEFAULT),
  AGG_HASH_TABLE_SIZE(ConfVars.$AGG_HASH_TABLE_SIZE, "Aggregation hash table size", DEFAULT),
  SORT_HASH_TABLE_SIZE(ConfVars.$SORT_HASH_TABLE_SIZE, "Sort hash table size", DEFAULT),
  JOIN_HASH_TABLE_SIZE(ConfVars.$JOIN_HASH_TABLE_SIZE, "Join hash table size", DEFAULT),

  // for index
  INDEX_ENABLED(ConfVars.$INDEX_ENABLED, "index scan enabled", DEFAULT),
  INDEX_SELECTIVITY_THRESHOLD(ConfVars.$INDEX_SELECTIVITY_THRESHOLD, "the selectivity threshold for index scan", DEFAULT),

  // for partition overwrite
  PARTITION_NO_RESULT_OVERWRITE_ENABLED(ConfVars.$PARTITION_NO_RESULT_OVERWRITE_ENABLED,
    "If True, a partitioned table is overwritten even if a sub query leads to no result. "
    + "Otherwise, the table data will be kept if there is no result", DEFAULT),

  // Behavior Control ---------------------------------------------------------
  ARITHABORT(ConfVars.$BEHAVIOR_ARITHMETIC_ABORT,
      "If true, a running query will be terminated when an overflow or divide-by-zero occurs.", DEFAULT),

  // ResultSet ----------------------------------------------------------------
  FETCH_ROWNUM(ConfVars.$RESULT_SET_FETCH_ROWNUM, "Sets the number of rows at a time from Master", DEFAULT,
      Integer.class, Validators.min("0")),
  BLOCK_ON_RESULT(ConfVars.$RESULT_SET_BLOCK_WAIT, "Whether to block result set on query execution", DEFAULT,
      Boolean.class, Validators.bool()),
  COMPRESSED_RESULT_TRANSFER(ConfVars.$COMPRESSED_RESULT_TRANSFER, "Use compression to optimize result transmission.",
      CLI_SIDE_VAR, Boolean.class, Validators.bool()),

  //-------------------------------------------------------------------------------
  // Only for Unit Testing
  //-------------------------------------------------------------------------------
  DEBUG_ENABLED(ConfVars.$DEBUG_ENABLED, "(debug only) debug mode enabled", DEFAULT),
  TEST_BROADCAST_JOIN_ENABLED(ConfVars.$TEST_BROADCAST_JOIN_ENABLED, "(test only) broadcast enabled", TEST_VAR),
  TEST_JOIN_OPT_ENABLED(ConfVars.$TEST_JOIN_OPT_ENABLED, "(test only) join optimization enabled", TEST_VAR),
  TEST_FILTER_PUSHDOWN_ENABLED(ConfVars.$TEST_FILTER_PUSHDOWN_ENABLED, "filter push down enabled", TEST_VAR),
  TEST_MIN_TASK_NUM(ConfVars.$TEST_MIN_TASK_NUM, "(test only) min task num", TEST_VAR),
  TEST_PLAN_SHAPE_FIX_ENABLED(ConfVars.$TEST_PLAN_SHAPE_FIX_ENABLED, "(test only) plan shape fix enabled", TEST_VAR),
  ;

  public static final Map<String, SessionVars> SESSION_VARS = Maps.newHashMap();
  public static final Map<String, SessionVars> DEPRECATED_SESSION_VARS = Maps.newHashMap();

  static {
    for (SessionVars var : SessionVars.values()) {
      SESSION_VARS.put(var.keyname(), var);
      DEPRECATED_SESSION_VARS.put(var.getConfVars().keyname(), var);
    }
  }

  private final ConfVars key;
  private final String description;
  private final VariableMode mode;
  
  private Class<?> valClass;
  private Validator validator;

  public static enum VariableMode {
    DEFAULT,         // Client can set or change variables of this mode..
    FROM_SHELL_ENV,  // This is similar to DEFAULT mode. In addition, it tries to get values from shell env. variables.
    SERVER_SIDE_VAR, // only TajoMaster is able to set and change variables of this mode.
    CLI_SIDE_VAR,    // This type variable is used in CLI.
    TEST_VAR         // Only used for unit tests
  }

  SessionVars(ConfVars key, String description, VariableMode mode) {
    this.key = key;
    this.description = description;
    this.mode = mode;
  }
  
  SessionVars(ConfVars key, String description, VariableMode mode, Class<?> valueClass, Validator validator) {
    this(key, description, mode);
    this.valClass = valueClass;
    this.validator = validator;
  }

  public String keyname() {
    return name();
  }

  public ConfigType type() {
    return ConfigType.SESSION;
  }

  public ConfVars getConfVars() {
    return key;
  }

  public Class<?> getVarType() {
    return key.valClass;
  }

  public String getDescription() {
    return description;
  }

  public VariableMode getMode() {
    return mode;
  }

  public static boolean exists(String keyname) {
    return SESSION_VARS.containsKey(keyname) || DEPRECATED_SESSION_VARS.containsKey(keyname);
  }

  public static boolean isDeprecated(String keyname) {
    return DEPRECATED_SESSION_VARS.containsKey(keyname);
  }

  public static boolean isPublic(SessionVars var) {
    return var.getMode() != SERVER_SIDE_VAR;
  }

  public static SessionVars get(String keyname) {
    if (SESSION_VARS.containsKey(keyname)) {
      return SESSION_VARS.get(keyname);
    } else if (DEPRECATED_SESSION_VARS.containsKey(keyname)) {
      return DEPRECATED_SESSION_VARS.get(keyname);
    } else {
      return null;
    }
  }

  /**
   * rename deprecated name to current name if the name is deprecated.
   *
   * @param keyname session variable name
   * @return The current session variable name
   */
  public static String handleDeprecatedName(String keyname) {
    return SessionVars.exists(keyname) ? SessionVars.get(keyname).keyname() : keyname;
  }

  @Override
  public Class<?> valueClass() {
    return valClass;
  }

  @Override
  public Validator validator() {
    return validator;
  }
}
