/*
 * 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 java.util.Arrays;

import com.google.common.base.Preconditions;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tajo.conf.TajoConf;
import org.apache.tajo.util.KeyValueSet;

import static org.apache.tajo.ConfigKey.ConfigType;
import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueSetProto;

/**
 * OverridableConf provides a consolidated config system. Tajo basically uses TajoConf, which is a extended class of
 * Hadoop's Configuration system, However, TajoConf is only used for sharing static system configs, such as binding
 * address of master and workers, system directories, other system parameters.
 *
 * For modifiable or instant configs, we use OverridableConf, which is a set of key-value pairs.
 * OverridableConf provides more strong-typed way to set configs and its behavior is more clear than Configuration
 * system.
 *
 * By default, OverridableConf recognizes following config types.
 *
 * <ul>
 *    <li>System Config - it comes from Hadoop's Configuration class. by tajo-site, catalog-site,
 *    catalog-default and TajoConf.</li>
 *    <li>Session variables - they are instantly configured by users.
 *    Each client session has it own set of session variables.</li>
 * </ul>
 *
 * System configs and session variables can set the same config in the same time. System configs are usually used to set
 * default configs, and session variables is user-specified configs. So, session variables can override system configs.
 */
public class OverridableConf extends KeyValueSet {
  private static final Log LOG = LogFactory.getLog(OverridableConf.class);
  private ConfigType [] configTypes;
  protected TajoConf conf;

  public OverridableConf(final TajoConf conf, ConfigType...configTypes) {
    this.conf = conf;
    this.configTypes = configTypes;
  }

  public OverridableConf(final TajoConf conf, KeyValueSetProto proto, ConfigType...configTypes) {
    super(proto);
    this.conf = conf;
    this.configTypes = configTypes;
  }

  public void setConf(TajoConf conf) {
    this.conf = conf;
  }

  public TajoConf getConf() {
    return conf;
  }

  public void setBool(ConfigKey key, boolean val) {
    setBool(key.keyname(), val);
  }

  public boolean getBool(ConfigKey key, Boolean defaultVal) {
    assertRegisteredEnum(key);

    if (key.type() != ConfigType.SESSION && key.type() != ConfigType.SYSTEM) {
      return getBool(key.keyname(), defaultVal);
    } else {
      switch (key.type()) {
      case QUERY:
        return getBool(key.keyname());
      case SESSION:
        return getBool(key.keyname(), conf.getBoolVar(((SessionVars) key).getConfVars()));
      case SYSTEM:
        return conf.getBoolVar((TajoConf.ConfVars) key);
      default:
        throw new IllegalStateException("key does not belong to Session and System config sets");
      }
    }
  }

  @Override
  public boolean getBool(ConfigKey key) {
    return getBool(key, null);
  }

  public void setInt(ConfigKey key, int val) {
    setInt(key.keyname(), val);
  }

  public int getInt(ConfigKey key, Integer defaultVal) {
    assertRegisteredEnum(key);

    if (key.type() != ConfigType.SESSION && key.type() != ConfigType.SYSTEM) {
      return getInt(key.keyname(), defaultVal);
    } else {
      switch (key.type()) {
      case SESSION:
        return getInt(key.keyname(), conf.getIntVar(((SessionVars) key).getConfVars()));
      case SYSTEM:
        return conf.getIntVar((TajoConf.ConfVars) key);
      default:
        throw new IllegalStateException("key does not belong to Session and System config sets");
      }
    }
  }

  @Override
  public int getInt(ConfigKey key) {
    return getInt(key, null);
  }

  public void setLong(ConfigKey key, long val) {
    setLong(key.keyname(), val);
  }

  public long getLong(ConfigKey key, Long defaultVal) {
    assertRegisteredEnum(key);

    if (key.type() != ConfigType.SESSION && key.type() != ConfigType.SYSTEM) {
      return getLong(key.keyname(), defaultVal);
    } else {
      switch (key.type()) {
      case SESSION:
        return getLong(key.keyname(), conf.getLongVar(((SessionVars) key).getConfVars()));
      case SYSTEM:
        return conf.getLongVar((TajoConf.ConfVars) key);
      default:
        throw new IllegalStateException("key does not belong to Session and System config sets");
      }
    }
  }

  @Override
  public long getLong(ConfigKey key) {
    return getLong(key, null);
  }

  public void setFloat(ConfigKey key, float val) {
    setFloat(key.keyname(), val);
  }

  public float getFloat(ConfigKey key, Float defaultVal) {
    assertRegisteredEnum(key);

    if (key.type() != ConfigType.SESSION && key.type() != ConfigType.SYSTEM) {
      return getFloat(key.keyname(), defaultVal);
    } else {
      switch (key.type()) {
      case SESSION:
        return getFloat(key.keyname(), conf.getFloatVar(((SessionVars) key).getConfVars()));
      case SYSTEM:
        return conf.getFloatVar((TajoConf.ConfVars) key);
      default:
        throw new IllegalStateException("key does not belong to Session and System config sets");
      }
    }
  }

  @Override
  public float getFloat(ConfigKey key) {
    return getFloat(key, null);
  }

  public void put(ConfigKey key, String val) {
    set(key.keyname(), val);
  }

  private void assertRegisteredEnum(ConfigKey key) {
    boolean registered = false;

    if (configTypes != null) {
      for (ConfigType c : configTypes) {
        registered = key.type() == c;
      }
    }

    // default permitted keys
    registered |= key.type() == ConfigType.SESSION || key.type() != ConfigType.SYSTEM;

    Preconditions.checkArgument(registered, key.keyname() + " (" + key.type() + ") is not allowed in " +
      getClass().getSimpleName());
  }

  public String get(ConfigKey key, String defaultVal) {
    assertRegisteredEnum(key);

    if (key.type() != ConfigType.SESSION && key.type() != ConfigType.SYSTEM) {
      return get(key.keyname(), defaultVal);
    } else {
      switch (key.type()) {
      case SESSION:
        return get(key.keyname(), conf.getVar(((SessionVars) key).getConfVars()));
      case SYSTEM:
        return conf.getVar((TajoConf.ConfVars) key);
      default:
        throw new IllegalStateException("key does not belong to Session and System config sets");
      }
    }
  }

  public String get(ConfigKey key) {
    return get(key, null);
  }

  public Class<?> getClass(ConfigKey key) {
    assertRegisteredEnum(key);

    String className = getTrimmed(key);
    try {
      return Class.forName(className);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
  }

  public String getTrimmed(ConfigKey key) {
    String value = get(key);

    if (null == value) {
      return null;
    } else {
      return value.trim();
    }
  }

  public boolean containsKey(ConfigKey key) {
    return containsKey(key.keyname());
  }

  public boolean equalKey(ConfigKey key, String another) {
    if (containsKey(key)) {
      return get(key).equals(another);
    } else {
      return false;
    }
  }
  
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + ((conf == null) ? 0 : conf.hashCode());
    result = prime * result + Arrays.hashCode(configTypes);
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    return super.equals(obj);
  }
  
}
