package com.cloudera.cmf.service.config;

import com.cloudera.cmf.model.DbHost;
import com.cloudera.cmf.model.DbHostHeartbeat;
import com.cloudera.cmf.model.DbRole;
import com.cloudera.cmf.model.DbService;
import com.cloudera.cmf.protocol.HostStatus;
import com.cloudera.cmf.service.ServiceDataProvider;
import com.cloudera.cmf.service.hdfs.HdfsConnector;
import com.cloudera.cmf.service.hdfs.NameNodeRoleHandler;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
import java.util.Set;

public class DfsHAFencingURLsEvaluator extends AbstractGenericConfigEvaluator
{
  private static final String DFS_HA_FENCING_CLOUDERA_MANAGER_AGENT_URL = "dfs.ha.fencing.cloudera_manager_agent.url";

  protected DfsHAFencingURLsEvaluator(Set<? extends Enum<?>> roleTypesToEmitFor)
  {
    super(roleTypesToEmitFor, null);
  }

  protected List<EvaluatedConfig> evaluateConfig(ConfigEvaluationContext context, String propertyName)
    throws ConfigGenException
  {
    ServiceDataProvider sdp = context.getSdp();
    DbService service = context.getService();

    HdfsConnector hdfsConnector = (HdfsConnector)ConfigEvaluatorHelpers.getCurrentOrDependencyConnector(sdp.getServiceHandlerRegistry(), service, HdfsConnector.TYPE);

    NameNodeRoleHandler nNRH = hdfsConnector.getNameNodeRoleHandler();

    List ecs = Lists.newArrayList();
    for (DbRole nn : hdfsConnector.getNameNodes()) {
      DbHost nnHost = nn.getHost();
      DbHostHeartbeat hb = nnHost.getHeartbeat();
      String nameNodeId = nNRH.getNameNodeId(nn);
      String nnHostName = nnHost.getName();
      StringBuilder agentUrl = new StringBuilder();
      if ((hb != null) && (hb.getHostStatus() != null) && (hb.getHostStatus().getAgentUrl() != null)) {
        agentUrl.append(hb.getHostStatus().getAgentUrl().toString());
      }
      else
      {
        agentUrl.append(String.format("http://%s:%d/", new Object[] { nnHostName, Integer.valueOf(9000) }));
      }
      agentUrl.append("fence/fence?name=");
      agentUrl.append(nNRH.makeProcessName(nn));
      agentUrl.append("&host=").append(nnHostName);
      agentUrl.append("&port=").append(nNRH.getPort(nn));

      ecs.add(new EvaluatedConfig(String.format("%s.%s", new Object[] { "dfs.ha.fencing.cloudera_manager_agent.url", nameNodeId }), agentUrl.toString()));

      Collections.sort(ecs, Collections.reverseOrder());
    }

    return ecs;
  }
}