package org.apache.helix;

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

/**
 * Types of nodes in a Helix cluster
 */
enum Type {
  CLUSTER,
  INSTANCE,
  CONTROLLER,
  RESOURCE,
  TASK,
  REST
}

/**
 * Types of data stored on Zookeeper by Helix
 */
public enum PropertyType {

  // @formatter:off
  // CLUSTER PROPERTIES
  CONFIGS(Type.CLUSTER, true, false, false, false, true),
  LIVEINSTANCES(Type.CLUSTER, false, false, false, true, true),
  INSTANCES(Type.CLUSTER, true, false),
  IDEALSTATES(Type.CLUSTER, true, false, false, false, true),
  EXTERNALVIEW(Type.CLUSTER, true, false),
  CUSTOMIZEDVIEW(Type.CLUSTER, true, false),
  TARGETEXTERNALVIEW(Type.CLUSTER, true, false),
  STATEMODELDEFS(Type.CLUSTER, true, false, false, false, true),
  CONTROLLER(Type.CLUSTER, true, false),
  PROPERTYSTORE(Type.CLUSTER, true, false),
  STATUS(Type.CLUSTER, true, false, true),

  // INSTANCE PROPERTIES
  MESSAGES(Type.INSTANCE, true, true, true),
  CURRENTSTATES(Type.INSTANCE, true, true, false, false, true),
  TASKCURRENTSTATES(Type.INSTANCE, true, true, false, false, true),
  STATUSUPDATES(Type.INSTANCE, true, true, false, false, false, true),
  ERRORS(Type.INSTANCE, true, true),
  INSTANCE_HISTORY(Type.INSTANCE, true, true, true),
  HEALTHREPORT(Type.INSTANCE, true, false, false, false, false, true),
  CUSTOMIZEDSTATES(Type.INSTANCE, true, false, false, true, true),


  // CONTROLLER PROPERTY
  LEADER(Type.CONTROLLER, false, false, true, true),
  HISTORY(Type.CONTROLLER, true, true, true),
  PAUSE(Type.CONTROLLER, true, false, true),
  MAINTENANCE(Type.CONTROLLER, true, false, true),
  MESSAGES_CONTROLLER(Type.CONTROLLER, true, false, true),
  STATUSUPDATES_CONTROLLER(Type.CONTROLLER, true, true, true),
  ERRORS_CONTROLLER(Type.CONTROLLER, true, true, true),

  // TASK PROPERTIES
  @Deprecated // This returns the old path for WorkflowContext
  WORKFLOWCONTEXT(Type.TASK, true, false, false, false, false),

  TASK_CONFIG_ROOT(Type.TASK, true, false, false, false, false),
  TASK_CONTEXT_ROOT(Type.TASK, true, false, false, false, false),
  WORKFLOW_CONFIG(Type.TASK, true, false, false, false, false),
  WORKFLOW_CONTEXT(Type.TASK, true, false, false, false, false),
  JOB_CONFIG(Type.TASK, true, false, false, false, false),
  JOB_CONTEXT(Type.TASK, true, false, false, false, false),

  // REST PROPERTIES
  RESTCONFIGS(Type.REST, true, false, false, false, true);

  // @formatter:on

  Type type;

  boolean isPersistent;

  boolean mergeOnUpdate;

  boolean updateOnlyOnExists;

  boolean createOnlyIfAbsent;

  /**
   * "isCached" defines whether the property is cached in data accessor if data is cached,
   * then read from zk can be optimized
   */
  boolean isCached;

  PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate) {
    this(type, isPersistent, mergeOnUpdate, false);
  }

  PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate, boolean updateOnlyOnExists) {
    this(type, isPersistent, mergeOnUpdate, false, false);
  }

  PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate, boolean updateOnlyOnExists,
      boolean createOnlyIfAbsent) {
    this(type, isPersistent, mergeOnUpdate, updateOnlyOnExists, createOnlyIfAbsent, false);
  }

  PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate, boolean updateOnlyOnExists,
      boolean createOnlyIfAbsent, boolean isCached) {
    this(type, isPersistent, mergeOnUpdate, updateOnlyOnExists, createOnlyIfAbsent, isCached,
        false);
  }

  PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate, boolean updateOnlyOnExists,
      boolean createOnlyIfAbsent, boolean isCached, boolean isAsyncWrite) {
    this.type = type;
    this.isPersistent = isPersistent;
    this.mergeOnUpdate = mergeOnUpdate;
    this.updateOnlyOnExists = updateOnlyOnExists;
    this.createOnlyIfAbsent = createOnlyIfAbsent;
    this.isCached = isCached;
  }

  /**
   * Determine if the property should only be created if it does not exist
   * @return true if it can only be created if absent, false otherwise
   */
  public boolean isCreateOnlyIfAbsent() {
    return createOnlyIfAbsent;
  }

  /**
   * Set policy for creating only if it does not already exist
   * @param createIfAbsent
   */
  public void setCreateIfAbsent(boolean createIfAbsent) {
    this.createOnlyIfAbsent = createIfAbsent;
  }

  /**
   * Gets the type of the associated node
   * @return {@link Type}
   */
  public Type getType() {
    return type;
  }

  /**
   * Set the type of the associated node
   * @param type {@link Type}
   */
  public void setType(Type type) {
    this.type = type;
  }

  /**
   * Get the persistent state of the property
   * @return true if persistent, false if ephemeral
   */
  public boolean isPersistent() {
    return isPersistent;
  }

  /**
   * Set the persistent state of the property
   * @param isPersistent
   */
  public void setPersistent(boolean isPersistent) {
    this.isPersistent = isPersistent;
  }

  /**
   * Determine if the property is merged or replaced on update
   * @return true if merge occurs on update, false otherwise
   */
  public boolean isMergeOnUpdate() {
    return mergeOnUpdate;
  }

  /**
   * Enable or disable merging on an update to this property
   * @param mergeOnUpdate
   */
  public void setMergeOnUpdate(boolean mergeOnUpdate) {
    this.mergeOnUpdate = mergeOnUpdate;
  }

  /**
   * Determine if this property is only updated if it exists
   * @return true if only updated when it exists, false otherwise
   */
  public boolean isUpdateOnlyOnExists() {
    return updateOnlyOnExists;
  }

  /**
   * Enable or disable updating only on existence
   * @param updateOnlyOnExists
   */
  public void setUpdateOnlyOnExists(boolean updateOnlyOnExists) {
    this.updateOnlyOnExists = updateOnlyOnExists;
  }

  /**
   * Check if value is cached
   * @return true if cached, false otherwise
   */
  public boolean isCached() {
    return isCached;
  }
}