// 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 com.cloud.deploy;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.org.Cluster;
import com.cloud.storage.StoragePool;
import com.cloud.utils.component.Adapter;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;

/**
 */
public interface DeploymentPlanner extends Adapter {
    /**
     * plan is called to determine where a virtual machine should be running.
     * 
     * @param vm
     *            virtual machine.
     * @param plan
     *            deployment plan that tells you where it's being deployed to.
     * @param avoid
     *            avoid these data centers, pods, clusters, or hosts.
     * @return DeployDestination for that virtual machine.
     */
    DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException;

    /**
     * check() is called right before the virtual machine starts to make sure
     * the host has enough capacity.
     * 
     * @param vm
     *            virtual machine in question.
     * @param plan
     *            deployment plan used to determined the deploy destination.
     * @param dest
     *            destination returned by plan.
     * @param avoid
     *            what to avoid.
     * @return true if it's okay to start; false if not. If false, the exclude list will include what should be
     *         excluded.
     */
    boolean check(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, DeployDestination dest, ExcludeList exclude);

    /**
     * canHandle is called before plan to determine if the plan can do the allocation. Planers should be exclusive so
     * planner writer must
     * make sure only one planer->canHandle return true in the planner list
     * 
     * @param vm
     *            virtual machine.
     * @param plan
     *            deployment plan that tells you where it's being deployed to.
     * @param avoid
     *            avoid these data centers, pods, clusters, or hosts.
     * @return true if it's okay to allocate; false or not
     */
    boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid);

    public enum AllocationAlgorithm {
        random,
        firstfit,
        userdispersing,
        userconcentratedpod_random,
        userconcentratedpod_firstfit;
    }

    public static class ExcludeList {
        private Set<Long> _dcIds;
        private Set<Long> _podIds;
        private Set<Long> _clusterIds;
        private Set<Long> _hostIds;
        private Set<Long> _poolIds;

        public ExcludeList() {
        }

        public ExcludeList(Set<Long> _dcIds, Set<Long> _podIds, Set<Long> _clusterIds, Set<Long> _hostIds, Set<Long> _poolIds) {
            this._dcIds = _dcIds;
            this._podIds = _podIds;
            this._clusterIds = _clusterIds;
            this._poolIds = _poolIds;
        }

        public boolean add(InsufficientCapacityException e) {
            Class<?> scope = e.getScope();

            if (scope == null) {
                return false;
            }

            if (Host.class.isAssignableFrom(scope)) {
                addHost(e.getId());
            } else if (Pod.class.isAssignableFrom(scope)) {
                addPod(e.getId());
            } else if (DataCenter.class.isAssignableFrom(scope)) {
                addDataCenter(e.getId());
            } else if (Cluster.class.isAssignableFrom(scope)) {
                addCluster(e.getId());
            } else if (StoragePool.class.isAssignableFrom(scope)) {
                addPool(e.getId());
            } else {
                return false;
            }

            return true;
        }

        public boolean add(ResourceUnavailableException e) {
            Class<?> scope = e.getScope();

            if (scope == null) {
                return false;
            }

            if (Host.class.isAssignableFrom(scope)) {
                addHost(e.getResourceId());
            } else if (Pod.class.isAssignableFrom(scope)) {
                addPod(e.getResourceId());
            } else if (DataCenter.class.isAssignableFrom(scope)) {
                addDataCenter(e.getResourceId());
            } else if (Cluster.class.isAssignableFrom(scope)) {
                addCluster(e.getResourceId());
            } else if (StoragePool.class.isAssignableFrom(scope)) {
                addPool(e.getResourceId());
            } else {
                return false;
            }

            return true;
        }

        public void addPool(long poolId) {
            if (_poolIds == null) {
                _poolIds = new HashSet<Long>();
            }
            _poolIds.add(poolId);
        }

        public void addDataCenter(long dataCenterId) {
            if (_dcIds == null) {
                _dcIds = new HashSet<Long>();
            }
            _dcIds.add(dataCenterId);
        }

        public void addPod(long podId) {
            if (_podIds == null) {
                _podIds = new HashSet<Long>();
            }
            _podIds.add(podId);
        }

        public void addCluster(long clusterId) {
            if (_clusterIds == null) {
                _clusterIds = new HashSet<Long>();
            }
            _clusterIds.add(clusterId);
        }

        public void addClusterList(Collection<Long> clusterList) {
            if (_clusterIds == null) {
                _clusterIds = new HashSet<Long>();
            }
            _clusterIds.addAll(clusterList);
        }
        
        public void addHost(long hostId) {
            if (_hostIds == null) {
                _hostIds = new HashSet<Long>();
            }
            _hostIds.add(hostId);
        }

        public boolean shouldAvoid(Host host) {
            if (_dcIds != null && _dcIds.contains(host.getDataCenterId())) {
                return true;
            }

            if (_podIds != null && _podIds.contains(host.getPodId())) {
                return true;
            }

            if (_clusterIds != null && _clusterIds.contains(host.getClusterId())) {
                return true;
            }

            if (_hostIds != null && _hostIds.contains(host.getId())) {
                return true;
            }

            return false;
        }

        public boolean shouldAvoid(Cluster cluster) {
            if (_dcIds != null && _dcIds.contains(cluster.getDataCenterId())) {
                return true;
            }

            if (_podIds != null && _podIds.contains(cluster.getPodId())) {
                return true;
            }

            if (_clusterIds != null && _clusterIds.contains(cluster.getId())) {
                return true;
            }
            return false;
        }

        public boolean shouldAvoid(Pod pod) {
            if (_dcIds != null && _dcIds.contains(pod.getDataCenterId())) {
                return true;
            }

            if (_podIds != null && _podIds.contains(pod.getId())) {
                return true;
            }

            return false;
        }

        public boolean shouldAvoid(StoragePool pool) {
            if (_dcIds != null && _dcIds.contains(pool.getDataCenterId())) {
                return true;
            }

            if (_podIds != null && _podIds.contains(pool.getPodId())) {
                return true;
            }

            if (_clusterIds != null && _clusterIds.contains(pool.getClusterId())) {
                return true;
            }

            if (_poolIds != null && _poolIds.contains(pool.getId())) {
                return true;
            }

            return false;
        }

        public boolean shouldAvoid(DataCenter dc) {
            if (_dcIds != null && _dcIds.contains(dc.getId())) {
                return true;
            }
            return false;
        }

        public Set<Long> getDataCentersToAvoid() {
            return _dcIds;
        }

        public Set<Long> getPodsToAvoid() {
            return _podIds;
        }

        public Set<Long> getClustersToAvoid() {
            return _clusterIds;
        }

        public Set<Long> getHostsToAvoid() {
            return _hostIds;
        }

        public Set<Long> getPoolsToAvoid() {
            return _poolIds;
        }
    }
}
