/*
 * 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.ambari.server.actionmanager;


import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.H2DatabaseCleaner;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.agent.AgentCommand.AgentCommandType;
import org.apache.ambari.server.agent.ExecutionCommand;
import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ConfigFactory;
import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
import org.apache.ambari.server.utils.StageUtils;
import org.codehaus.jettison.json.JSONException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class ExecutionCommandWrapperTest {

  private static final String HOST1 = "dev01.ambari.apache.org";
  private static final String CLUSTER1 = "c1";
  private static final String CLUSTER_VERSION_TAG = "clusterVersion";
  private static final String SERVICE_VERSION_TAG = "serviceVersion";
  private static final String HOST_VERSION_TAG = "hostVersion";
  private static final String GLOBAL_CONFIG = "global";
  private static final String SERVICE_SITE_CONFIG = "service-site";
  private static final String SERVICE_SITE_NAME1 = "ssn1";
  private static final String SERVICE_SITE_NAME2 = "ssn2";
  private static final String SERVICE_SITE_NAME3 = "ssn3";
  private static final String SERVICE_SITE_NAME4 = "ssn4";
  private static final String SERVICE_SITE_NAME5 = "ssn5";
  private static final String SERVICE_SITE_NAME6 = "ssn6";
  private static final String SERVICE_SITE_VAL1 = "ssv1";
  private static final String SERVICE_SITE_VAL1_S = "ssv1_s";
  private static final String SERVICE_SITE_VAL2 = "ssv2";
  private static final String SERVICE_SITE_VAL2_H = "ssv2_h";
  private static final String SERVICE_SITE_VAL3 = "ssv3";
  private static final String SERVICE_SITE_VAL4 = "ssv4";
  private static final String SERVICE_SITE_VAL5 = "ssv5";
  private static final String SERVICE_SITE_VAL5_S = "ssv5_s";
  private static final String SERVICE_SITE_VAL6_H = "ssv6_h";
  private static final String GLOBAL_NAME1 = "gn1";
  private static final String GLOBAL_NAME2 = "gn2";
  private static final String GLOBAL_CLUSTER_VAL1 = "gcv1";
  private static final String GLOBAL_CLUSTER_VAL2 = "gcv2";
  private static final String GLOBAL_VAL1 = "gv1";

  private static Map<String, String> GLOBAL_CLUSTER;
  private static Map<String, String> SERVICE_SITE_CLUSTER;
  private static Map<String, String> SERVICE_SITE_SERVICE;
  private static Map<String, String> SERVICE_SITE_HOST;
  private static Map<String, Map<String, String>> CONFIG_ATTRIBUTES;

  private static Injector injector;
  private static Clusters clusters;
  private static ConfigFactory configFactory;
  private static ConfigHelper configHelper;
  private static StageFactory stageFactory;
  private static OrmTestHelper ormTestHelper;

  @BeforeClass
  public static void setup() throws AmbariException {
    injector = Guice.createInjector(new InMemoryDefaultTestModule());
    injector.getInstance(GuiceJpaInitializer.class);
    configHelper = injector.getInstance(ConfigHelper.class);
    configFactory = injector.getInstance(ConfigFactory.class);
    stageFactory = injector.getInstance(StageFactory.class);
    ormTestHelper = injector.getInstance(OrmTestHelper.class);

    clusters = injector.getInstance(Clusters.class);
    clusters.addHost(HOST1);
    StackId stackId = new StackId("HDP-0.1");
    clusters.addCluster(CLUSTER1, stackId);

    Cluster cluster1 = clusters.getCluster(CLUSTER1);

    OrmTestHelper helper = injector.getInstance(OrmTestHelper.class);
    RepositoryVersionEntity repositoryVersion = helper.getOrCreateRepositoryVersion(cluster1);
    cluster1.addService("HDFS", repositoryVersion);

    SERVICE_SITE_CLUSTER = new HashMap<>();
    SERVICE_SITE_CLUSTER.put(SERVICE_SITE_NAME1, SERVICE_SITE_VAL1);
    SERVICE_SITE_CLUSTER.put(SERVICE_SITE_NAME2, SERVICE_SITE_VAL2);
    SERVICE_SITE_CLUSTER.put(SERVICE_SITE_NAME3, SERVICE_SITE_VAL3);
    SERVICE_SITE_CLUSTER.put(SERVICE_SITE_NAME4, SERVICE_SITE_VAL4);

    SERVICE_SITE_SERVICE = new HashMap<>();
    SERVICE_SITE_SERVICE.put(SERVICE_SITE_NAME1, SERVICE_SITE_VAL1_S);
    SERVICE_SITE_SERVICE.put(SERVICE_SITE_NAME5, SERVICE_SITE_VAL5_S);

    SERVICE_SITE_HOST = new HashMap<>();
    SERVICE_SITE_HOST.put(SERVICE_SITE_NAME2, SERVICE_SITE_VAL2_H);
    SERVICE_SITE_HOST.put(SERVICE_SITE_NAME6, SERVICE_SITE_VAL6_H);

    GLOBAL_CLUSTER = new HashMap<>();
    GLOBAL_CLUSTER.put(GLOBAL_NAME1, GLOBAL_CLUSTER_VAL1);
    GLOBAL_CLUSTER.put(GLOBAL_NAME2, GLOBAL_CLUSTER_VAL2);

    CONFIG_ATTRIBUTES = new HashMap<>();

    //Cluster level global config
    configFactory.createNew(stackId, cluster1, GLOBAL_CONFIG, CLUSTER_VERSION_TAG, GLOBAL_CLUSTER,
        CONFIG_ATTRIBUTES);

    //Cluster level service config
    configFactory.createNew(stackId, cluster1, SERVICE_SITE_CONFIG, CLUSTER_VERSION_TAG,
        SERVICE_SITE_CLUSTER, CONFIG_ATTRIBUTES);

    //Service level service config
    configFactory.createNew(stackId, cluster1, SERVICE_SITE_CONFIG, SERVICE_VERSION_TAG,
        SERVICE_SITE_SERVICE, CONFIG_ATTRIBUTES);

    //Host level service config
    configFactory.createNew(stackId, cluster1, SERVICE_SITE_CONFIG, HOST_VERSION_TAG, SERVICE_SITE_HOST,
        CONFIG_ATTRIBUTES);

    ActionDBAccessor db = injector.getInstance(ActionDBAccessorImpl.class);

    createTask(db, 1, 1, HOST1, CLUSTER1);

  }

  private static void createTask(ActionDBAccessor db, long requestId, long stageId, String hostName, String clusterName) throws AmbariException {

    Stage s = stageFactory.createNew(requestId, "/var/log", clusterName, 1L, "execution command wrapper test", "commandParamsStage", "hostParamsStage");
    s.setStageId(stageId);
    s.addHostRoleExecutionCommand(hostName, Role.NAMENODE,
        RoleCommand.START,
        new ServiceComponentHostStartEvent(Role.NAMENODE.toString(),
            hostName, System.currentTimeMillis()), clusterName, "HDFS", false, false);
    List<Stage> stages = new ArrayList<>();
    stages.add(s);
    Request request = new Request(stages, "clusterHostInfo", clusters);
    db.persistActions(request);
  }

  @Test
  public void testGetExecutionCommand() throws JSONException, AmbariException {
    Map<String, Map<String, String>> confs = new HashMap<>();
    Map<String, String> configurationsGlobal = new HashMap<>();
    configurationsGlobal.put(GLOBAL_NAME1, GLOBAL_VAL1);
    confs.put(GLOBAL_CONFIG, configurationsGlobal);

    Map<String, Map<String, String>> confTags = new HashMap<>();
    Map<String, String> confTagServiceSite = new HashMap<>();

    confTagServiceSite.put("tag", CLUSTER_VERSION_TAG);
    confTagServiceSite.put("service_override_tag", SERVICE_VERSION_TAG);
    confTagServiceSite.put("host_override_tag", HOST_VERSION_TAG);

    confTags.put(SERVICE_SITE_CONFIG, confTagServiceSite);

    Map<String, String> confTagGlobal = Collections.singletonMap("tag", CLUSTER_VERSION_TAG);

    confTags.put(GLOBAL_CONFIG, confTagGlobal);


    ExecutionCommand executionCommand = new ExecutionCommand();


    executionCommand.setClusterName(CLUSTER1);
    executionCommand.setTaskId(1);
    executionCommand.setRequestAndStage(1, 1);
    executionCommand.setHostname(HOST1);
    executionCommand.setRole("NAMENODE");
    executionCommand.setRoleParams(Collections.<String, String>emptyMap());
    executionCommand.setRoleCommand(RoleCommand.START);
    executionCommand.setConfigurations(confs);
    executionCommand.setConfigurationTags(confTags);
    executionCommand.setServiceName("HDFS");
    executionCommand.setCommandType(AgentCommandType.EXECUTION_COMMAND);
    executionCommand.setCommandParams(Collections.<String, String>emptyMap());

    String json = StageUtils.getGson().toJson(executionCommand, ExecutionCommand.class);

    ExecutionCommandWrapper execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    ExecutionCommand processedExecutionCommand = execCommWrap.getExecutionCommand();

    Map<String, String> serviceSiteConfig = processedExecutionCommand.getConfigurations().get(SERVICE_SITE_CONFIG);

    Assert.assertEquals(SERVICE_SITE_VAL1_S, serviceSiteConfig.get(SERVICE_SITE_NAME1));
    Assert.assertEquals(SERVICE_SITE_VAL2_H, serviceSiteConfig.get(SERVICE_SITE_NAME2));
    Assert.assertEquals(SERVICE_SITE_VAL3, serviceSiteConfig.get(SERVICE_SITE_NAME3));
    Assert.assertEquals(SERVICE_SITE_VAL4, serviceSiteConfig.get(SERVICE_SITE_NAME4));
    Assert.assertEquals(SERVICE_SITE_VAL5_S, serviceSiteConfig.get(SERVICE_SITE_NAME5));
    Assert.assertEquals(SERVICE_SITE_VAL6_H, serviceSiteConfig.get(SERVICE_SITE_NAME6));

    Map<String, String> globalConfig = processedExecutionCommand.getConfigurations().get(GLOBAL_CONFIG);

    Assert.assertEquals(GLOBAL_VAL1, globalConfig.get(GLOBAL_NAME1));
    Assert.assertEquals(GLOBAL_CLUSTER_VAL2, globalConfig.get(GLOBAL_NAME2));


    //Union of all keys of service site configs
    Set<String> serviceSiteKeys = new HashSet<>();
    serviceSiteKeys.addAll(SERVICE_SITE_CLUSTER.keySet());
    serviceSiteKeys.addAll(SERVICE_SITE_SERVICE.keySet());
    serviceSiteKeys.addAll(SERVICE_SITE_HOST.keySet());

    Assert.assertEquals(serviceSiteKeys.size(), serviceSiteConfig.size());

  }

  @Test
  public void testGetMergedConfig() {
    Map<String, String> baseConfig = new HashMap<>();

    baseConfig.put(SERVICE_SITE_NAME1, SERVICE_SITE_VAL1);
    baseConfig.put(SERVICE_SITE_NAME2, SERVICE_SITE_VAL2);
    baseConfig.put(SERVICE_SITE_NAME3, SERVICE_SITE_VAL3);
    baseConfig.put(SERVICE_SITE_NAME4, SERVICE_SITE_VAL4);
    baseConfig.put(SERVICE_SITE_NAME5, SERVICE_SITE_VAL5);

    Map<String, String> overrideConfig = new HashMap<>();

    overrideConfig.put(SERVICE_SITE_NAME2, SERVICE_SITE_VAL2_H);
    overrideConfig.put(SERVICE_SITE_NAME6, SERVICE_SITE_VAL6_H);


    Map<String, String> mergedConfig = configHelper.getMergedConfig(baseConfig,
      overrideConfig);


    Set<String> configsKeys = new HashSet<>();
    configsKeys.addAll(baseConfig.keySet());
    configsKeys.addAll(overrideConfig.keySet());

    Assert.assertEquals(configsKeys.size(), mergedConfig.size());

    Assert.assertEquals(SERVICE_SITE_VAL1, mergedConfig.get(SERVICE_SITE_NAME1));
    Assert.assertEquals(SERVICE_SITE_VAL2_H, mergedConfig.get(SERVICE_SITE_NAME2));
    Assert.assertEquals(SERVICE_SITE_VAL3, mergedConfig.get(SERVICE_SITE_NAME3));
    Assert.assertEquals(SERVICE_SITE_VAL4, mergedConfig.get(SERVICE_SITE_NAME4));
    Assert.assertEquals(SERVICE_SITE_VAL5, mergedConfig.get(SERVICE_SITE_NAME5));
    Assert.assertEquals(SERVICE_SITE_VAL6_H, mergedConfig.get(SERVICE_SITE_NAME6));
  }

  /**
   * Test that the execution command wrapper properly sets the version
   * information when the cluster is in the INSTALLING state.
   *
   * @throws JSONException
   * @throws AmbariException
   */
  @Test
  public void testExecutionCommandHasVersionInfoWithoutCurrentClusterVersion()
      throws JSONException, AmbariException {
    Cluster cluster = clusters.getCluster(CLUSTER1);

    StackId stackId = cluster.getDesiredStackVersion();
    
    // set the repo version resolved state to verify that the version is not sent
    RepositoryVersionEntity repositoryVersion = ormTestHelper.getOrCreateRepositoryVersion(stackId, "0.1-0000");
    repositoryVersion.setResolved(false);
    ormTestHelper.repositoryVersionDAO.merge(repositoryVersion);

    Service service = cluster.getService("HDFS");
    service.setDesiredRepositoryVersion(repositoryVersion);

    // first try with an INSTALL command - this should not populate version info
    ExecutionCommand executionCommand = new ExecutionCommand();
    Map<String, String> commandParams = new HashMap<>();

    executionCommand.setClusterName(CLUSTER1);
    executionCommand.setTaskId(1);
    executionCommand.setRequestAndStage(1, 1);
    executionCommand.setHostname(HOST1);
    executionCommand.setRole("NAMENODE");
    executionCommand.setRoleParams(Collections.<String, String>emptyMap());
    executionCommand.setRoleCommand(RoleCommand.INSTALL);
    executionCommand.setServiceName("HDFS");
    executionCommand.setCommandType(AgentCommandType.EXECUTION_COMMAND);
    executionCommand.setCommandParams(commandParams);

    String json = StageUtils.getGson().toJson(executionCommand, ExecutionCommand.class);
    ExecutionCommandWrapper execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    ExecutionCommand processedExecutionCommand = execCommWrap.getExecutionCommand();
    commandParams = processedExecutionCommand.getCommandParams();
    Assert.assertFalse(commandParams.containsKey(KeyNames.VERSION));

    // now try with a START command, but still unresolved
    executionCommand = new ExecutionCommand();
    commandParams = new HashMap<>();

    executionCommand.setClusterName(CLUSTER1);
    executionCommand.setTaskId(1);
    executionCommand.setRequestAndStage(1, 1);
    executionCommand.setHostname(HOST1);
    executionCommand.setRole("NAMENODE");
    executionCommand.setRoleParams(Collections.<String, String> emptyMap());
    executionCommand.setRoleCommand(RoleCommand.START);
    executionCommand.setServiceName("HDFS");
    executionCommand.setCommandType(AgentCommandType.EXECUTION_COMMAND);
    executionCommand.setCommandParams(commandParams);

    json = StageUtils.getGson().toJson(executionCommand, ExecutionCommand.class);
    execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    processedExecutionCommand = execCommWrap.getExecutionCommand();
    commandParams = processedExecutionCommand.getCommandParams();
    Assert.assertFalse(commandParams.containsKey(KeyNames.VERSION));

    // now that the repositoryVersion is resolved, it should populate the version even
    // though the state is INSTALLING
    repositoryVersion.setResolved(true);
    ormTestHelper.repositoryVersionDAO.merge(repositoryVersion);
    execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    processedExecutionCommand = execCommWrap.getExecutionCommand();
    commandParams = processedExecutionCommand.getCommandParams();
    Assert.assertEquals("0.1-0000", commandParams.get(KeyNames.VERSION));
  }

  /**
   * Test that the execution command wrapper ignores repository file when there are none to use.
   */
  @Test
  public void testExecutionCommandNoRepositoryFile() throws Exception {
    Cluster cluster = clusters.getCluster(CLUSTER1);

    StackId stackId = cluster.getDesiredStackVersion();
    RepositoryVersionEntity repositoryVersion = ormTestHelper.getOrCreateRepositoryVersion(stackId, "0.1-0000");
    repositoryVersion.setResolved(true); // has build number
    Service service = cluster.getService("HDFS");
    service.setDesiredRepositoryVersion(repositoryVersion);

    repositoryVersion.setOperatingSystems("[]");

    ormTestHelper.repositoryVersionDAO.merge(repositoryVersion);

    // first try with an INSTALL command - this should not populate version info
    ExecutionCommand executionCommand = new ExecutionCommand();
    Map<String, String> commandParams = new HashMap<>();

    executionCommand.setClusterName(CLUSTER1);
    executionCommand.setTaskId(1);
    executionCommand.setRequestAndStage(1, 1);
    executionCommand.setHostname(HOST1);
    executionCommand.setRole("NAMENODE");
    executionCommand.setRoleParams(Collections.<String, String>emptyMap());
    executionCommand.setRoleCommand(RoleCommand.INSTALL);
    executionCommand.setServiceName("HDFS");
    executionCommand.setCommandType(AgentCommandType.EXECUTION_COMMAND);
    executionCommand.setCommandParams(commandParams);

    String json = StageUtils.getGson().toJson(executionCommand, ExecutionCommand.class);
    ExecutionCommandWrapper execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    ExecutionCommand processedExecutionCommand = execCommWrap.getExecutionCommand();
    commandParams = processedExecutionCommand.getCommandParams();
    Assert.assertFalse(commandParams.containsKey(KeyNames.VERSION));

    // now try with a START command which should populate the version even
    // though the state is INSTALLING
    executionCommand = new ExecutionCommand();
    commandParams = new HashMap<>();

    executionCommand.setClusterName(CLUSTER1);
    executionCommand.setTaskId(1);
    executionCommand.setRequestAndStage(1, 1);
    executionCommand.setHostname(HOST1);
    executionCommand.setRole("NAMENODE");
    executionCommand.setRoleParams(Collections.<String, String> emptyMap());
    executionCommand.setRoleCommand(RoleCommand.START);
    executionCommand.setServiceName("HDFS");
    executionCommand.setCommandType(AgentCommandType.EXECUTION_COMMAND);
    executionCommand.setCommandParams(commandParams);

    json = StageUtils.getGson().toJson(executionCommand, ExecutionCommand.class);
    execCommWrap = new ExecutionCommandWrapper(json);
    injector.injectMembers(execCommWrap);

    processedExecutionCommand = execCommWrap.getExecutionCommand();
    commandParams = processedExecutionCommand.getCommandParams();
    Assert.assertEquals("0.1-0000", commandParams.get(KeyNames.VERSION));
  }

  @AfterClass
  public static void tearDown() throws AmbariException, SQLException {
    H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector);
  }
}
