// Copyright 2016 Twitter. All rights reserved.
//
// Licensed 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.storm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.esotericsoftware.kryo.Serializer;

import org.apache.storm.serialization.IKryoDecorator;
import org.apache.storm.serialization.IKryoFactory;

/**
 * Topology configs are specified as a plain old map. This class provides a
 * convenient way to create a topology config map by providing setter methods for
 * all the configs that can be set. It also makes it easier to do things like add
 * serializations.
 * <p>
 * <p>This class also provides constants for all the configurations possible on a Storm
 * cluster and Storm topology. Default values for these configs can be found in
 * defaults.yaml.</p>
 * <p>
 * <p>Note that you may put other configurations in any of the configs. Storm
 * will ignore anything it doesn't recognize, but your topologies are free to make
 * use of them by reading them in the prepare method of Bolts or the open method of
 * Spouts. .</p>
 */
public class Config extends com.twitter.heron.api.Config {
  private static final long serialVersionUID = 4781760255471579334L;

  /**
   * True if Storm should timeout messages or not. Defaults to true. This is meant to be used
   * in unit tests to prevent tuples from being accidentally timed out during the test.
   * Same functionality in Heron.
   */
  public static final String TOPOLOGY_ENABLE_MESSAGE_TIMEOUTS = "topology.enable.message.timeouts";
  /**
   * Whether or not the master should optimize topologies by running multiple
   * tasks in a single thread where appropriate.
   * This has no impact in Heron
   */
  public static final String TOPOLOGY_OPTIMIZE = "topology.optimize";
  /**
   * How many instances to create for a spout/bolt. A task runs on a thread with zero or more
   * other tasks for the same spout/bolt. The number of tasks for a spout/bolt is always
   * the same throughout the lifetime of a topology, but the number of executors (threads) for
   * a spout/bolt can change over time. This allows a topology to scale to more or less resources
   * without redeploying the topology or violating the constraints of Storm (such as a fields grouping
   * guaranteeing that the same value goes to the same task).
   * This has no impact on Heron.
   */
  public static final String TOPOLOGY_TASKS = "topology.tasks";
  /**
   * A list of serialization registrations for Kryo ( http://code.google.com/p/kryo/ ),
   * the underlying serialization framework for Storm. A serialization can either
   * be the name of a class (in which case Kryo will automatically create a serializer for the class
   * that saves all the object's fields), or an implementation of com.esotericsoftware.kryo.Serializer.
   * <p>
   * See Kryo's documentation for more information about writing custom serializers.
   * Same in Heron.
   */
  public static final String TOPOLOGY_KRYO_REGISTER = "topology.kryo.register";
  /**
   * A list of classes that customize storm's kryo instance during start-up.
   * Each listed class name must implement IKryoDecorator. During start-up the
   * listed class is instantiated with 0 arguments, then its 'decorate' method
   * is called with storm's kryo instance as the only argument.
   * Same in Heron.
   */
  public static final String TOPOLOGY_KRYO_DECORATORS = "topology.kryo.decorators";
  /**
   * Class that specifies how to create a Kryo instance for serialization. Storm will then apply
   * topology.kryo.register and topology.kryo.decorators on top of this. The default implementation
   * implements topology.fall.back.on.java.serialization and turns references off.
   * Same in Heron.
   */
  public static final String TOPOLOGY_KRYO_FACTORY = "topology.kryo.factory";
  /**
   * Whether or not Storm should skip the loading of kryo registrations for which it
   * does not know the class or have the serializer implementation. Otherwise, the task will
   * fail to load and will throw an error at runtime. The use case of this is if you want to
   * declare your serializations on the storm.yaml files on the cluster rather than every single
   * time you submit a topology. Different applications may use different serializations and so
   * a single application may not have the code for the other serializers used by other apps.
   * By setting this config to true, Storm will ignore that it doesn't have those other serializations
   * rather than throw an error.
   * Same in Heron.
   */
  public static final String TOPOLOGY_SKIP_MISSING_KRYO_REGISTRATIONS =
      "topology.skip.missing.kryo.registrations";
  /**
   * The maximum amount of time a component gives a source of state to synchronize before it requests
   * synchronization again.
   * This is not implemented in Heron.
   */
  public static final String TOPOLOGY_STATE_SYNCHRONIZATION_TIMEOUT_SECS =
      "topology.state.synchronization.timeout.secs";
  /**
   * Whether or not to use Java serialization in a topology.
   * This has the same meaning in Heron.
   */
  public static final String TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION =
      "topology.fall.back.on.java.serialization";
  /**
   * Topology-specific options for the worker child process. This is used in addition to WORKER_CHILDOPTS.
   * Not yet implemented in Heron.
   */
  public static final String TOPOLOGY_WORKER_CHILDOPTS = "topology.worker.childopts";
  /**
   * This config is available for TransactionalSpouts, and contains the id ( a String) for
   * the transactional topology. This id is used to store the state of the transactional
   * topology in Zookeeper.
   * This is not implemented in Heron.
   */
  public static final String TOPOLOGY_TRANSACTIONAL_ID = "topology.transactional.id";
  /**
   * How often a tick tuple from the "__system" component and "__tick" stream should be sent
   * to tasks. Meant to be used as a component-specific configuration.
   * Same meaning in Heron.
   */
  public static final String TOPOLOGY_TICK_TUPLE_FREQ_SECS = "topology.tick.tuple.freq.secs";
  /**
   * The interval in seconds to use for determining whether to throttle error reported to Zookeeper. For example,
   * an interval of 10 seconds with topology.max.error.report.per.interval set to 5 will only allow 5 errors to be
   * reported to Zookeeper per task for every 10 second interval of time.
   * This is not supported in Heron.
   */
  public static final String TOPOLOGY_ERROR_THROTTLE_INTERVAL_SECS =
      "topology.error.throttle.interval.secs";
  /**
   * See doc for TOPOLOGY_ERROR_THROTTLE_INTERVAL_SECS.
   * This is not supported in Heron
   */
  public static final String TOPOLOGY_MAX_ERROR_REPORT_PER_INTERVAL =
      "topology.max.error.report.per.interval";
  /**
   * When set to true, Storm will log every message that's emitted.
   */
  public static final String TOPOLOGY_DEBUG = "topology.debug";
  /**
   * This currently gets translated to TOPOLOGY_STMGRS. Please see the
   * documentation for TOPOLOGY_STMGRS.
   */
  public static final String TOPOLOGY_WORKERS = "topology.workers";
  /**
   * How many executors to spawn for ackers.
   * <p>If this is set to 0, then Storm will immediately ack tuples as soon
   * as they come off the spout, effectively disabling reliability.</p>
   * In Heron any values of > 0 means to enable acking.
   */
  public static final String TOPOLOGY_ACKER_EXECUTORS = "topology.acker.executors";
  /**
   * The maximum amount of time given to the topology to fully process a message
   * emitted by a spout. If the message is not acked within this time frame, Storm
   * will fail the message on the spout. Some spouts implementations will then replay
   * the message at a later time.
   * This has the same meaning in Heron.
   */
  public static final String TOPOLOGY_MESSAGE_TIMEOUT_SECS = "topology.message.timeout.secs";
  /*
   * A list of classes implementing IMetricsConsumer (See storm.yaml.example for exact config format).
   * Each listed class will be routed all the metrics data generated by the storm metrics API.
   * Each listed class maps 1:1 to a system bolt named __metrics_ClassName#N, and it's parallelism is configurable.
   * This is not supported by Heron.
   */
  public static final String TOPOLOGY_METRICS_CONSUMER_REGISTER =
      "topology.metrics.consumer.register";
  /**
   * The maximum parallelism allowed for a component in this topology. This configuration is
   * typically used in testing to limit the number of threads spawned in local mode.
   * This does not have any impact in Heron
   */
  public static final String TOPOLOGY_MAX_TASK_PARALLELISM = "topology.max.task.parallelism";
  /**
   * The maximum number of tuples that can be pending on a spout task at any given time.
   * This config applies to individual tasks, not to spouts or topologies as a whole.
   * <p>
   * A pending tuple is one that has been emitted from a spout but has not been acked or failed yet.
   * Note that this config parameter has no effect for unreliable spouts that don't tag
   * their tuples with a message id.
   * This has same meaning in Heron.
   */
  public static final String TOPOLOGY_MAX_SPOUT_PENDING = "topology.max.spout.pending";
  /**
   * A class that implements a strategy for what to do when a spout needs to wait. Waiting is
   * triggered in one of two conditions:
   * <p>
   * 1. nextTuple emits no tuples
   * 2. The spout has hit maxSpoutPending and can't emit any more tuples
   * This is not yet implemented in Heron.
   */
  public static final String TOPOLOGY_SPOUT_WAIT_STRATEGY = "topology.spout.wait.strategy";
  /**
   * The amount of milliseconds the SleepEmptyEmitStrategy should sleep for.
   * This is not yet implemented in Heron
   */
  public static final String TOPOLOGY_SLEEP_SPOUT_WAIT_STRATEGY_TIME_MS =
      "topology.sleep.spout.wait.strategy.time.ms";
  /**
   * The percentage of tuples to sample to produce stats for a task.
   * This is not implemented in Heron.
   */
  public static final String TOPOLOGY_STATS_SAMPLE_RATE = "topology.stats.sample.rate";
  /**
   * A list of task hooks that are automatically added to every spout and bolt in the topology. An example
   * of when you'd do this is to add a hook that integrates with your internal
   * monitoring system. These hooks are instantiated using the zero-arg constructor.
   */
  public static final String TOPOLOGY_AUTO_TASK_HOOKS = "topology.auto.task.hooks";
  /**
   * Name of the topology. This config is automatically set by Storm when the topology is submitted.
   * Same in Heron
   */
  public static final String TOPOLOGY_NAME = "topology.name";


  /**
   * Name of the team which owns this topology.
   * Same in Heron
   */
  public static final String TOPOLOGY_TEAM_NAME = "topology.team.name";

  /**
   * Email of the team which owns this topology.
   * Same in Heron
   */
  public static final String TOPOLOGY_TEAM_EMAIL = "topology.team.email";

  /**
   * Cap ticket (if filed) for the topology. If the topology is in prod this has to be set or it
   * cannot be deployed.
   * Same in Heron
   */
  public static final String TOPOLOGY_CAP_TICKET = "topology.cap.ticket";

  /**
   * Project name of the topology, to help us with tagging which topologies are part of which project. For example, if topology A and
   * Topology B are part of the same project, we will like to aggregate them as part of the same project. This is required by Cap team.
   * Same in Heron
   */
  public static final String TOPOLOGY_PROJECT_NAME = "topology.project.name";

  /**
   * ----  DO NOT USE -----
   * This variable is used to rewrite the TOPOLOGY_AUTO_TASK_HOOKS variable.
   * As such this is a strictly internal config variable that is not exposed the user
   */
  public static final String STORMCOMPAT_TOPOLOGY_AUTO_TASK_HOOKS =
      "stormcompat.topology.auto.task.hooks";

  public static void setDebug(Map<String, Object> conf, boolean isOn) {
    conf.put(Config.TOPOLOGY_DEBUG, isOn);
  }

  public static void setTeamName(Map<String, Object> conf, String teamName) {
    conf.put(Config.TOPOLOGY_TEAM_NAME, teamName);
  }

  public static void setTeamEmail(Map<String, Object> conf, String teamEmail) {
    conf.put(Config.TOPOLOGY_TEAM_EMAIL, teamEmail);
  }

  public static void setTopologyCapTicket(Map<String, Object> conf, String ticket) {
    conf.put(Config.TOPOLOGY_CAP_TICKET, ticket);
  }

  public static void setTopologyProjectName(Map<String, Object> conf, String project) {
    conf.put(Config.TOPOLOGY_PROJECT_NAME, project);
  }

  public static void setNumWorkers(Map<String, Object> conf, int workers) {
    conf.put(Config.TOPOLOGY_WORKERS, workers);
  }

  public static void setNumAckers(Map<String, Object> conf, int numExecutors) {
    conf.put(Config.TOPOLOGY_ACKER_EXECUTORS, numExecutors);
  }

  public static void setMessageTimeoutSecs(Map<String, Object> conf, int secs) {
    conf.put(Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS, secs);
  }

  public static void registerSerialization(Map<String, Object> conf, Class klass) {
    getRegisteredSerializations(conf).add(klass.getName());
  }

  public static void registerSerialization(
      Map<String, Object> conf, Class klass, Class<? extends Serializer> serializerClass) {
    Map<String, String> register = new HashMap<>();
    register.put(klass.getName(), serializerClass.getName());
    getRegisteredSerializations(conf).add(register);
  }

  public static void registerDecorator(
      Map<String, Object> conf,
      Class<? extends IKryoDecorator> klass) {
    getRegisteredDecorators(conf).add(klass.getName());
  }

  public static void setKryoFactory(Map<String, Object> conf, Class<? extends IKryoFactory> klass) {
    conf.put(Config.TOPOLOGY_KRYO_FACTORY, klass.getName());
  }

  public static void setSkipMissingKryoRegistrations(Map<String, Object> conf, boolean skip) {
    conf.put(Config.TOPOLOGY_SKIP_MISSING_KRYO_REGISTRATIONS, skip);
  }

  public static void setMaxTaskParallelism(Map<String, Object> conf, int max) {
    conf.put(Config.TOPOLOGY_MAX_TASK_PARALLELISM, max);
  }

  public static void setMaxSpoutPending(Map<String, Object> conf, int max) {
    conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, max);
  }

  public static void setStatsSampleRate(Map<String, Object> conf, double rate) {
    conf.put(Config.TOPOLOGY_STATS_SAMPLE_RATE, rate);
  }

  public static void setFallBackOnJavaSerialization(Map<String, Object> conf, boolean fallback) {
    conf.put(Config.TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION, fallback);
  }

  @SuppressWarnings("rawtypes") // List can contain strings or maps
  private static List getRegisteredSerializations(Map<String, Object> conf) {
    List ret;
    if (!conf.containsKey(Config.TOPOLOGY_KRYO_REGISTER)) {
      ret = new ArrayList();
    } else {
      ret = new ArrayList((List) conf.get(Config.TOPOLOGY_KRYO_REGISTER));
    }
    conf.put(Config.TOPOLOGY_KRYO_REGISTER, ret);
    return ret;
  }

  private static List<String> getRegisteredDecorators(Map<String, Object> conf) {
    List<String> ret;
    if (!conf.containsKey(Config.TOPOLOGY_KRYO_DECORATORS)) {
      ret = new ArrayList<>();
    } else {
      ret = new ArrayList<>((List<String>) conf.get(Config.TOPOLOGY_KRYO_DECORATORS));
    }
    conf.put(Config.TOPOLOGY_KRYO_DECORATORS, ret);
    return ret;
  }

  public void setDebug(boolean isOn) {
    setDebug(this, isOn);
  }

  public void setTeamName(String teamName) {
    setTeamName(this, teamName);
  }

  public void setTeamEmail(String teamEmail) {
    setTeamEmail(this, teamEmail);
  }

  public void setTopologyCapTicket(String ticket) {
    setTopologyCapTicket(this, ticket);
  }

  public void setTopologyProjectName(String project) {
    setTopologyProjectName(this, project);
  }

  /**
   * Set topology optimization
   * @param isOn
   * @deprecated we don't have optimization
   */
  @Deprecated
  public void setOptimize(boolean isOn) {
    put(Config.TOPOLOGY_OPTIMIZE, isOn);
  }

  public void setNumWorkers(int workers) {
    setNumWorkers(this, workers);
  }

  public void setNumAckers(int numExecutors) {
    setNumAckers(this, numExecutors);
  }

  public void setMessageTimeoutSecs(int secs) {
    setMessageTimeoutSecs(this, secs);
  }

  public void registerSerialization(Class klass) {
    registerSerialization(this, klass);
  }

  public void registerSerialization(Class klass, Class<? extends Serializer> serializerClass) {
    registerSerialization(this, klass, serializerClass);
  }

  public void registerMetricsConsumer(Class klass, Object argument, long parallelismHint) {
    HashMap<String, Object> m = new HashMap<>();
    m.put("class", klass.getCanonicalName());
    m.put("parallelism.hint", parallelismHint);
    m.put("argument", argument);

    List<Map<String, Object>> l =
        (List<Map<String, Object>>) this.get(TOPOLOGY_METRICS_CONSUMER_REGISTER);
    if (l == null) {
      l = new ArrayList<>();
    }
    l.add(m);
    this.put(TOPOLOGY_METRICS_CONSUMER_REGISTER, l);
  }

  public void registerMetricsConsumer(Class klass, long parallelismHint) {
    registerMetricsConsumer(klass, null, parallelismHint);
  }

  public void registerMetricsConsumer(Class klass) {
    registerMetricsConsumer(klass, null, 1L);
  }

  public void registerDecorator(Class<? extends IKryoDecorator> klass) {
    registerDecorator(this, klass);
  }

  public void setKryoFactory(Class<? extends IKryoFactory> klass) {
    setKryoFactory(this, klass);
  }

  public void setSkipMissingKryoRegistrations(boolean skip) {
    setSkipMissingKryoRegistrations(this, skip);
  }

  public void setMaxTaskParallelism(int max) {
    setMaxTaskParallelism(this, max);
  }

  public void setMaxSpoutPending(int max) {
    setMaxSpoutPending(this, max);
  }

  public void setStatsSampleRate(double rate) {
    setStatsSampleRate(this, rate);
  }

  public void setFallBackOnJavaSerialization(boolean fallback) {
    setFallBackOnJavaSerialization(this, fallback);
  }
}

