/*
 * 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.hadoop.yarn.api.records.Container
import org.apache.slider.api.StatusKeys
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.operations.AbstractRMOperation
import org.apache.slider.server.appmaster.state.NodeEntry
import org.apache.slider.server.appmaster.state.NodeInstance
import org.apache.slider.server.appmaster.state.NodeMap
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 TestMockAppStateRebuildOnAMRestart extends BaseMockAppStateTest
    implements MockRoles {

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

  @Test
  public void testRebuild() throws Throwable {

    int r0 = 1
    int r1 = 2
    int r2 = 3
    role0Status.desired = r0
    role1Status.desired = r1
    role2Status.desired = r2
    List<RoleInstance> instances = createAndStartNodes()

    int clusterSize = r0 + r1 + r2
    assert instances.size() == clusterSize

    //clone the list
    List<RoleInstance> cloned = [];
    List<Container> containers = []
    instances.each { RoleInstance elt ->
      cloned.add(elt.clone() as RoleInstance)
      containers.add(elt.container)
    }
    NodeMap nodemap = appState.roleHistory.cloneNodemap()

    // now destroy the app state
    appState = new MockAppState()

    //and rebuild
    appState.buildInstance(
        factory.newInstanceDefinition(r0, r1, r2),
        new Configuration(),
        new Configuration(false),
        factory.ROLES,
        fs,
        historyPath,
        containers,
        null, new SimpleReleaseSelector())

    assert appState.getStartedCountainerCount() == clusterSize

    appState.getRoleHistory().dump();

    //check that the app state direct structures match
    List<RoleInstance> r0live = appState.enumLiveNodesInRole(ROLE0)
    List<RoleInstance> r1live = appState.enumLiveNodesInRole(ROLE1)
    List<RoleInstance> r2live = appState.enumLiveNodesInRole(ROLE2)

    assert r0 == r0live.size()
    assert r1 == r1live.size()
    assert r2 == r2live.size()

    //now examine the role history
    NodeMap newNodemap = appState.roleHistory.cloneNodemap()

    for (NodeInstance nodeInstance : newNodemap.values()) {
      String hostname = nodeInstance.hostname
      NodeInstance orig = nodemap[hostname]
      assertNotNull("Null entry in original nodemap for " + hostname, orig)

      for (int i = 0; i < ROLE_COUNT; i++) {
        
        assert (nodeInstance.getActiveRoleInstances(i) ==
                orig.getActiveRoleInstances(i))
        NodeEntry origRE = orig.getOrCreate(i)
        NodeEntry newRE = nodeInstance.getOrCreate(i)
        assert origRE.live == newRE.live
        assert newRE.starting == 0
      }
    }
    List<AbstractRMOperation> ops = appState.reviewRequestAndReleaseNodes()
    assert ops.size() == 0

    def status = appState.getClusterStatus()
    // verify the AM restart container count was set
    String restarted = status.getInfo(
        StatusKeys.INFO_CONTAINERS_AM_RESTART)
    assert restarted != null;
    //and that the count == 1 master + the region servers
    assert Integer.parseInt(restarted) == containers.size()
  }
}
