/**
 * 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.hdfs.tools;

import java.net.InetSocketAddress;
import java.util.Map;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ha.BadFencingConfigurationException;
import org.apache.hadoop.ha.HAServiceTarget;
import org.apache.hadoop.ha.NodeFencer;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSUtil;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.net.NetUtils;

import com.google.common.base.Preconditions;

/**
 * One of the NN NameNodes acting as the target of an administrative command
 * (e.g. failover).
 */
@InterfaceAudience.Private
public class NNHAServiceTarget extends HAServiceTarget {

  // Keys added to the fencing script environment
  private static final String NAMESERVICE_ID_KEY = "nameserviceid";
  private static final String NAMENODE_ID_KEY = "namenodeid";
  
  private final InetSocketAddress addr;
  private InetSocketAddress zkfcAddr;
  private NodeFencer fencer;
  private BadFencingConfigurationException fenceConfigError;
  private final String nnId;
  private final String nsId;
  private final boolean autoFailoverEnabled;
  
  public NNHAServiceTarget(Configuration conf,
      String nsId, String nnId) {
    Preconditions.checkNotNull(nnId);
    
    if (nsId == null) {
      nsId = DFSUtil.getOnlyNameServiceIdOrNull(conf);
      if (nsId == null) {
        throw new IllegalArgumentException(
            "Unable to determine the nameservice id.");
      }
    }
    assert nsId != null;
    
    // Make a copy of the conf, and override configs based on the
    // target node -- not the node we happen to be running on.
    HdfsConfiguration targetConf = new HdfsConfiguration(conf);
    NameNode.initializeGenericKeys(targetConf, nsId, nnId);
    
    String serviceAddr = 
      DFSUtil.getNamenodeServiceAddr(targetConf, nsId, nnId);
    if (serviceAddr == null) {
      throw new IllegalArgumentException(
          "Unable to determine service address for namenode '" + nnId + "'");
    }
    this.addr = NetUtils.createSocketAddr(serviceAddr,
        NameNode.DEFAULT_PORT);

    this.autoFailoverEnabled = targetConf.getBoolean(
        DFSConfigKeys.DFS_HA_AUTO_FAILOVER_ENABLED_KEY,
        DFSConfigKeys.DFS_HA_AUTO_FAILOVER_ENABLED_DEFAULT);
    if (autoFailoverEnabled) {
      int port = DFSZKFailoverController.getZkfcPort(targetConf);
      if (port != 0) {
        setZkfcPort(port);
      }
    }
    
    try {
      this.fencer = NodeFencer.create(targetConf,
          DFSConfigKeys.DFS_HA_FENCE_METHODS_KEY);
    } catch (BadFencingConfigurationException e) {
      this.fenceConfigError = e;
    }
    
    this.nnId = nnId;
    this.nsId = nsId;
  }

  /**
   * @return the NN's IPC address.
   */
  @Override
  public InetSocketAddress getAddress() {
    return addr;
  }

  @Override
  public InetSocketAddress getZKFCAddress() {
    Preconditions.checkState(autoFailoverEnabled,
        "ZKFC address not relevant when auto failover is off");
    assert zkfcAddr != null;
    
    return zkfcAddr;
  }
  
  void setZkfcPort(int port) {
    assert autoFailoverEnabled;
          
    this.zkfcAddr = new InetSocketAddress(addr.getAddress(), port);
  }

  @Override
  public void checkFencingConfigured() throws BadFencingConfigurationException {
    if (fenceConfigError != null) {
      throw fenceConfigError;
    }
    if (fencer == null) {
      throw new BadFencingConfigurationException(
          "No fencer configured for " + this);
    }
  }
  
  @Override
  public NodeFencer getFencer() {
    return fencer;
  }
  
  @Override
  public String toString() {
    return "NameNode at " + addr;
  }

  public String getNameServiceId() {
    return this.nsId;
  }
  
  public String getNameNodeId() {
    return this.nnId;
  }

  @Override
  protected void addFencingParameters(Map<String, String> ret) {
    super.addFencingParameters(ret);
    
    ret.put(NAMESERVICE_ID_KEY, getNameServiceId());
    ret.put(NAMENODE_ID_KEY, getNameNodeId());
  }

  @Override
  public boolean isAutoFailoverEnabled() {
    return autoFailoverEnabled;
  }
}
