/**
 * 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.hadoop.hbase;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.ReflectionUtils;

/**
 * Facility for <strong>integration/system</strong> tests. This extends {@link HBaseTestingUtility}
 * and adds-in the functionality needed by integration and system tests. This class understands
 * distributed and pseudo-distributed/local cluster deployments, and abstracts those from the tests
 * in this module.
 * <p>
 * IntegrationTestingUtility is constructed and used by the integration tests, but the tests
 * themselves should not assume a particular deployment. They can rely on the methods in this
 * class and HBaseCluster. Before the testing begins, the test should initialize the cluster by
 * calling {@link #initializeCluster(int)}.
 * <p>
 * The cluster that is used defaults to a mini cluster, but it can be forced to use a distributed
 * cluster by calling {@link #setUseDistributedCluster(Configuration)}. This method is invoked by
 * test drivers (maven, IntegrationTestsDriver, etc) before initializing the cluster
 * via {@link #initializeCluster(int)}. Individual tests should not directly call
 * {@link #setUseDistributedCluster(Configuration)}.
 */
public class IntegrationTestingUtility extends HBaseTestingUtility {

  public IntegrationTestingUtility() {
    this(HBaseConfiguration.create());
  }

  public IntegrationTestingUtility(Configuration conf) {
    super(conf);
  }

  /**
   * Configuration that controls whether this utility assumes a running/deployed cluster.
   * This is different than "hbase.cluster.distributed" since that parameter indicates whether the
   * cluster is in an actual distributed environment, while this shows that there is a
   * deployed (distributed or pseudo-distributed) cluster running, and we do not need to
   * start a mini-cluster for tests.
   */
  public static final String IS_DISTRIBUTED_CLUSTER = "hbase.test.cluster.distributed";

  /** Config for pluggable hbase cluster manager */
  private static final String HBASE_CLUSTER_MANAGER_CLASS = "hbase.it.clustermanager.class";
  private static final Class<? extends ClusterManager> DEFAULT_HBASE_CLUSTER_MANAGER_CLASS = 
    HBaseClusterManager.class;
  
  /**
   * Initializes the state of the cluster. It starts a new in-process mini cluster, OR
   * if we are given an already deployed distributed cluster it initializes the state.
   * @param numSlaves Number of slaves to start up if we are booting a mini cluster. Otherwise
   * we check whether this many nodes are available and throw an exception if not.
   */
  public void initializeCluster(int numSlaves) throws Exception {
    if (isDistributedCluster()) {
      createDistributedHBaseCluster();
      checkNodeCount(numSlaves);
    } else {
      startMiniCluster(numSlaves);
    }
  }

  /**
   * Checks whether we have more than numSlaves nodes. Throws an
   * exception otherwise.
   */
  public void checkNodeCount(int numSlaves) throws Exception {
    HBaseCluster cluster = getHBaseClusterInterface();
    if (cluster.getClusterStatus().getServers().size() < numSlaves) {
      throw new Exception("Cluster does not have enough nodes:" + numSlaves);
    }
  }

  /**
   * Restores the cluster to the initial state if it is a distributed cluster, otherwise, shutdowns the
   * mini cluster.
   */
  public void restoreCluster() throws IOException {
    if (isDistributedCluster()) {
      getHBaseClusterInterface().restoreInitialStatus();
    } else {
      try {
        shutdownMiniCluster();
      } catch (Exception e) {
        // re-wrap into IOException
        throw new IOException(e);
      }
    }
  }

  /**
   * Sets the configuration property to use a distributed cluster for the integration tests. Test drivers
   * should use this to enforce cluster deployment.
   */
  public static void setUseDistributedCluster(Configuration conf) {
    conf.setBoolean(IS_DISTRIBUTED_CLUSTER, true);
    System.setProperty(IS_DISTRIBUTED_CLUSTER, "true");
  }

  /**
   * @return whether we are interacting with a distributed cluster as opposed to and in-process mini
   * cluster or a local cluster.
   * @see IntegrationTestingUtility#setUseDistributedCluster(Configuration)
   */
  public boolean isDistributedCluster() {
    Configuration conf = getConfiguration();
    boolean isDistributedCluster = false;
    isDistributedCluster = Boolean.parseBoolean(System.getProperty(IS_DISTRIBUTED_CLUSTER, "false"));
    if (!isDistributedCluster) {
      isDistributedCluster = conf.getBoolean(IS_DISTRIBUTED_CLUSTER, false);
    }
    return isDistributedCluster;
  }

  public void createDistributedHBaseCluster() throws IOException {
    Configuration conf = getConfiguration();
    Class<? extends ClusterManager> clusterManagerClass = conf.getClass(HBASE_CLUSTER_MANAGER_CLASS,
      DEFAULT_HBASE_CLUSTER_MANAGER_CLASS, ClusterManager.class);
    ClusterManager clusterManager = ReflectionUtils.newInstance(
      clusterManagerClass, conf);
    setHBaseCluster(new DistributedHBaseCluster(conf, clusterManager));
    getHBaseAdmin();
  }

}
