/*
 * 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.slider.agent.standalone

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.hadoop.yarn.api.records.ApplicationReport
import org.apache.slider.agent.AgentMiniClusterTestBase
import org.apache.slider.api.ClusterDescription
import org.apache.slider.api.ResourceKeys
import org.apache.slider.client.SliderClient
import org.apache.slider.common.SliderExitCodes
import org.apache.slider.common.params.SliderActions
import org.apache.slider.core.exceptions.SliderException
import org.apache.slider.core.main.LauncherExitCodes
import org.apache.slider.core.main.ServiceLauncher
import org.junit.Test

import static org.apache.slider.common.params.Arguments.ARG_COMP_OPT
import static org.apache.slider.common.params.Arguments.ARG_RESOURCE_OPT
import static org.apache.slider.common.params.Arguments.ARG_RES_COMP_OPT
import static org.apache.slider.providers.agent.AgentKeys.SERVICE_NAME

@CompileStatic
@Slf4j

class TestBuildStandaloneAM extends AgentMiniClusterTestBase {

  @Test
  public void testBuildCluster() throws Throwable {
    String clustername = createMiniCluster("", configuration, 1, true)

    describe "verify that a build cluster is created but not started"

    ServiceLauncher<SliderClient> launcher = createOrBuildCluster(
        SliderActions.ACTION_BUILD,
        clustername,
        [:],
        [ARG_RESOURCE_OPT, "yarn.container.failure.window.years", "4"],
        true,
        false,
        agentDefOptions)
    SliderClient sliderClient = launcher.service
    addToTeardown(sliderClient);

    //verify that exists(live) is now false
    assert LauncherExitCodes.EXIT_FALSE ==
           sliderClient.actionExists(clustername, true)

    //but the cluster is still there for the default
    assert 0 == sliderClient.actionExists(clustername, false)
    
    
    
    // verify the YARN registry doesn't know of it
    def serviceRegistryClient = sliderClient.YARNRegistryClient
    ApplicationReport report = serviceRegistryClient.findInstance(clustername)
    assert report == null;
    
    // verify that global resource options propagate from the CLI
    def aggregateConf = sliderClient.loadPersistedClusterDescription(clustername)
    def windowDays = aggregateConf.resourceOperations.globalOptions.getMandatoryOptionInt(
        "yarn.container.failure.window.years")
    assert 4 == windowDays

    //and a second attempt will fail as the cluster now exists
    try {
      ServiceLauncher<SliderClient> cluster2 = createOrBuildCluster(
          SliderActions.ACTION_BUILD,
          clustername,
          [:],
          [],
          false,
          false,
          agentDefOptions)
      fail("expected an exception, got $cluster2.service")
    } catch (SliderException e) {
      assertExceptionDetails(e, SliderExitCodes.EXIT_INSTANCE_EXISTS, "")
    }

    
    
    //thaw time
    ServiceLauncher<SliderClient> l2 = thawCluster(clustername, [], true)
    SliderClient thawed = l2.service
    addToTeardown(thawed);
    waitForClusterLive(thawed)
  }

  @Test
  public void testUpdateCluster() throws Throwable {
    String clustername = createMiniCluster("", configuration, 1, true)

    describe "verify that a built cluster can be updated"

    ServiceLauncher<SliderClient> launcher = createOrBuildCluster(
        SliderActions.ACTION_BUILD,
        clustername,
        [:],
        [],
        true,
        false,
        agentDefOptions)
    SliderClient sliderClient = launcher.service
    addToTeardown(sliderClient);

    //verify that exists(live) is now false
    assert LauncherExitCodes.EXIT_FALSE ==
           sliderClient.actionExists(clustername, true)

    //but the cluster is still there for the default
    assert 0 == sliderClient.actionExists(clustername, false)

    def serviceRegistryClient = sliderClient.YARNRegistryClient
    ApplicationReport report = serviceRegistryClient.findInstance(clustername)
    assert report == null;

    def master = "hbase-master"
    createOrBuildCluster(
        SliderActions.ACTION_UPDATE,
        clustername,
        [(master): 1],
        [
            ARG_RES_COMP_OPT, master, ResourceKeys.COMPONENT_PRIORITY, "2",
            ARG_COMP_OPT, master, SERVICE_NAME, "HBASE",
        ],
        true,
        false,
        agentDefOptions)

    launcher = thawCluster(clustername, [], true);
    sliderClient = launcher.service
    addToTeardown(sliderClient);
    waitForClusterLive(sliderClient)

    dumpClusterStatus(sliderClient, "application status after update")

    ClusterDescription cd = sliderClient.clusterDescription
    Map<String, String> masterRole = cd.getRole(master)
    assert masterRole != null, "Role hbase-master must exist"
    assert cd.roleNames.contains(master), "Role names must contain hbase-master"
  }
}
