// 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.network.vpc;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.cloudstack.acl.ControlledEntity.ACLType;

import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.addr.PublicIp;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;


public interface VpcManager extends VpcService{

    /**
     * Returns all existing VPCs for a given account
     * @param accountId
     * @return
     */
    List<? extends Vpc> getVpcsForAccount(long accountId);

    
    /**
     * Destroys the VPC
     * 
     * @param vpc
     * @param caller TODO
     * @param callerUserId TODO
     * @return
     * @throws ConcurrentOperationException
     * @throws ResourceUnavailableException
     */
    boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException;


    /**
     * Returns true if the IP is allocated to the VPC; false otherwise
     * 
     * @param ip
     * @return
     */
    boolean isIpAllocatedToVpc(IpAddress ip);


    /**
     * Disassociates the public IP address from VPC
     * 
     * @param ipId
     * @param networkId
     */
    void unassignIPFromVpcNetwork(long ipId, long networkId);


    /**
     * Creates guest network in the VPC
     * 
     * @param ntwkOffId
     * @param name
     * @param displayText
     * @param gateway
     * @param cidr
     * @param vlanId
     * @param networkDomain
     * @param owner
     * @param domainId
     * @param pNtwk
     * @param zoneId
     * @param aclType
     * @param subdomainAccess
     * @param vpcId
     * @param caller
     * @return
     * @throws ConcurrentOperationException
     * @throws InsufficientCapacityException
     * @throws ResourceAllocationException
     */
    Network createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway, String cidr, 
            String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork pNtwk, long zoneId,
            ACLType aclType, Boolean subdomainAccess, long vpcId, Account caller) 
                    throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;


    /**
     * Assigns source nat public IP address to VPC
     * 
     * @param owner
     * @param vpc
     * @return public IP address object
     * @throws InsufficientAddressCapacityException
     * @throws ConcurrentOperationException
     */
    PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException;


    /**
     * Validates network offering to find if it can be used for network creation in VPC
     * 
     * @param guestNtwkOff
     * @param supportedSvcs TODO
     */
    void validateNtwkOffForVpc(NetworkOffering guestNtwkOff, List<Service> supportedSvcs);


    /**
     * @return list of hypervisors that are supported by VPC
     */
    List<HypervisorType> getSupportedVpcHypervisors();
    
    
    /**
     * Lists all the services and providers that the current VPC suppots
     * @param vpcOffId
     * @return map of Service to Provider(s) map 
     */
    Map<Service, Set<Provider>> getVpcOffSvcProvidersMap(long vpcOffId);
    
    
    /**
     * Returns VPC that is ready to be used
     * @param vpcId
     * @return VPC object
     */
    public Vpc getActiveVpc(long vpcId);


    /**
     * Performs network offering validation to determine if it can be used for network upgrade inside the VPC 
     * @param networkId
     * @param newNtwkOffId
     * @param newCidr
     * @param newNetworkDomain
     * @param vpc
     * @param gateway
     * @param networkOwner TODO
     */
    void validateNtwkOffForNtwkInVpc(Long networkId, long newNtwkOffId, String newCidr, String newNetworkDomain, Vpc vpc, String gateway, Account networkOwner);
}
