/*
 * 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.mock

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.hadoop.yarn.client.api.AMRMClient

/**
 * Provides allocation services to a cluster -both random and placed.
 *
 * Important: container allocations need an app attempt ID put into the container ID
 */
@CompileStatic
@Slf4j
class Allocator {

  final MockYarnCluster cluster;
  /**
   * Rolling index into the cluster used for the
   * next "random" assignment
   */
  private int rollingIndex = 0;

  Allocator(MockYarnCluster cluster) {
    this.cluster = cluster
  }

  /**
   * Allocate a node using the list of nodes in the container as the
   * hints.
   * @param request request
   * @return the allocated container -or null for none
   */
  MockContainer allocate(AMRMClient.ContainerRequest request) {
    MockYarnCluster.MockYarnClusterNode node = null
    MockYarnCluster.MockYarnClusterContainer allocated = null
    if (request.nodes != null) {
      for (String host : request.nodes) {
        node = cluster.lookup(host)
        allocated = node.allocate()
        if (allocated != null) {
          break
        }
      }
    }

    if (allocated) {
      return createContainerRecord(request, allocated, node)
    } else {
      if (request.relaxLocality || request.nodes.isEmpty()) {
        // fallback to anywhere
        return allocateRandom(request)
      } else {
        //no match and locality can't be requested
        return null;
      }
    }
  }

  /**
   * Allocate a node without any positioning -use whatever policy this allocator
   * chooses.
   * @param request request
   * @return the allocated container -or null for none
   */
  MockContainer allocateRandom(AMRMClient.ContainerRequest request) {
    int start = rollingIndex;
    MockYarnCluster.MockYarnClusterNode node = cluster.nodeAt(rollingIndex)
    MockYarnCluster.MockYarnClusterContainer allocated = node.allocate();
    // if there is no space, try again -but stop when all the nodes
    // have failed
    while (allocated == null && start != nextIndex()) {
      node = cluster.nodeAt(rollingIndex)
      allocated = node.allocate();
    }

    //here the allocation is set, so create the response 
    return createContainerRecord(request, allocated, node)
  }

  /**
   * Create a container record -if one was allocated
   * @param allocated allocation -may be null
   * @param node node with the container
   * @return a container record, or null if there was no allocation
   */
  public MockContainer createContainerRecord(
      AMRMClient.ContainerRequest request,
      MockYarnCluster.MockYarnClusterContainer allocated,
      MockYarnCluster.MockYarnClusterNode node) {
    if (allocated == null) {
      // no space
      return null;
    }
    MockContainer container = new MockContainer()
    container.id = new MockContainerId(allocated.cid)
    container.nodeId = node.nodeId
    container.nodeHttpAddress = node.httpAddress()
    container.priority = request.priority
    return container;
  }

  private int nextIndex() {
    rollingIndex = (rollingIndex + 1) % cluster.clusterSize;
    return rollingIndex;
  }

}
