/*
 * 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.server.appmaster.model.appstate

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.hadoop.conf.Configuration
import org.apache.slider.api.ResourceKeys
import org.apache.slider.common.tools.SliderUtils
import org.apache.slider.core.conf.ConfTreeOperations
import org.apache.slider.server.appmaster.model.mock.BaseMockAppStateTest
import org.apache.slider.server.appmaster.model.mock.MockAppState
import org.apache.slider.server.appmaster.model.mock.MockRoles
import org.apache.slider.server.appmaster.model.mock.MockYarnEngine
import org.apache.slider.server.appmaster.operations.AbstractRMOperation
import org.apache.slider.server.appmaster.state.RoleInstance
import org.apache.slider.server.appmaster.state.SimpleReleaseSelector
import org.junit.Test

/**
 * Test that if you have >1 role, the right roles are chosen for release.
 */
@CompileStatic
@Slf4j
class TestMockAppStateDynamicRoles extends BaseMockAppStateTest
    implements MockRoles {

  @Override
  String getTestName() {
    return "TestMockAppStateDynamicRoles"
  }

  /**
   * Small cluster with multiple containers per node,
   * to guarantee many container allocations on each node
   * @return
   */
  @Override
  MockYarnEngine createYarnEngine() {
    return new MockYarnEngine(4, 4)
  }

  @Override
  void initApp() {
    super.initApp()
    appState = new MockAppState()
    appState.setContainerLimits(RM_MAX_RAM, RM_MAX_CORES)

    def instance = factory.newInstanceDefinition(0,0,0)

    def opts = [
        (ResourceKeys.COMPONENT_INSTANCES): "1",
        (ResourceKeys.COMPONENT_PRIORITY): "4",
    ]

    instance.resourceOperations.components["dynamic"]= opts
    
    
    appState.buildInstance(
        instance,
        new Configuration(),
        new Configuration(false),
        factory.ROLES,
        fs,
        historyPath,
        null,
        null, new SimpleReleaseSelector())
  }

  @Test
  public void testAllocateReleaseRealloc() throws Throwable {

    List<RoleInstance> instances = createAndStartNodes()
    List<AbstractRMOperation> ops = appState.reviewRequestAndReleaseNodes()
    appState.getRoleHistory().dump();
    
  }


  @Test
  public void testDynamicRoleHistory() throws Throwable {

    // snapshot and patch existing spec
    def resources = ConfTreeOperations.fromInstance(
        appState.resourcesSnapshot.confTree)

    def name = "dynamic"
    def dynamicComp = resources.getOrAddComponent(name)
    int priority = 8
    int placement = 3
    dynamicComp.put(ResourceKeys.COMPONENT_PRIORITY, "8")
    dynamicComp.put(ResourceKeys.COMPONENT_INSTANCES, "1")
    dynamicComp.put(ResourceKeys.COMPONENT_PLACEMENT_POLICY, "3")

    def component = resources.getComponent(name)
    String priOpt = component.getMandatoryOption(
        ResourceKeys.COMPONENT_PRIORITY);
    int parsedPriority = SliderUtils.parseAndValidate(
        "value of " + name + " " + ResourceKeys.COMPONENT_PRIORITY,
        priOpt, 0, 1, -1);
    assert priority == parsedPriority

    def newRole = appState.createDynamicProviderRole(name, component)
    assert newRole.id == priority
    
    appState.updateResourceDefinitions(resources.confTree);
    assert appState.roleMap[name] != null
    def mappedRole = appState.roleMap[name]
    assert mappedRole.id == priority

    def priorityMap = appState.rolePriorityMap
    assert priorityMap.size() == 4
    def dynamicProviderRole
    assert (dynamicProviderRole = priorityMap[priority]) != null
    assert dynamicProviderRole.id == priority

    // allocate the nodes
    def allocations = createAndStartNodes()
    assert allocations.size() == 1
    RoleInstance ri = allocations[0]
    assert ri.role == name
    assert ri.roleId == priority
  }
}
