//
// 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.guru;

import java.util.List;

import javax.inject.Inject;

import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.CreateBcfAttachmentCommand;
import com.cloud.agent.api.CreateBcfRouterCommand;
import com.cloud.agent.api.CreateBcfRouterInterfaceCommand;
import com.cloud.agent.api.CreateBcfSegmentCommand;
import com.cloud.agent.api.DeleteBcfSegmentCommand;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkProfile;
import com.cloud.network.NetworkService;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.bigswitch.BigSwitchBcfUtils;
import com.cloud.network.dao.BigSwitchBcfDao;
import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.vpc.NetworkACLItemCidrsDao;
import com.cloud.network.vpc.NetworkACLItemDao;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.VMInstanceDao;

/**
 * BigSwitchBcfGuestNetworkGuru is responsible for creating and removing virtual networks.
 * Current implementation leverages GuestNetworkGuru to create VLAN based virtual networks
 * and map it to a Big Switch Big Cloud Fabric (BCF) Segment.  It is called by the NetworkOrchestrator.
 *
 * When a VM is created and needs to be plugged into a BCF segment network, BigSwitchBcfElement is
 * called by NetworkOrchestrator to create a "port" and an "attachment" for each nic, and
 * register them with the controller to be plugged into the corresponding network. It also
 * removes them when the VM is destroyed.
 */
public class BigSwitchBcfGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigrationResponder {

    @Inject
    PhysicalNetworkDao _physicalNetworkDao;
    @Inject
    BigSwitchBcfDao _bigswitchBcfDao;
    @Inject
    HostDao _hostDao;
    @Inject
    AgentManager _agentMgr;
    @Inject
    DomainRouterDao _routerDao;
    @Inject
    VMInstanceDao _vmDao;
    @Inject
    AccountDao _accountDao;
    @Inject
    VpcDao _vpcDao;
    @Inject
    IPAddressDao _ipAddressDao;
    @Inject
    HostPodDao _podDao;
    @Inject
    NetworkService _netService;
    @Inject
    VlanDao _vlanDao;
    @Inject
    FirewallRulesDao _fwRulesDao;
    @Inject
    FirewallRulesCidrsDao _fwCidrsDao;
    @Inject
    NetworkACLItemDao _aclItemDao;
    @Inject
    NetworkACLItemCidrsDao _aclItemCidrsDao;

    private BigSwitchBcfUtils _bcfUtils = null;

    public BigSwitchBcfGuestNetworkGuru() {
        super();
        _isolationMethods = new IsolationMethod[] {new IsolationMethod("BCF_SEGMENT")};
    }

    @Override
    protected boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) {
        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated &&
            isMyIsolationMethod(physicalNetwork)) {
            return true;
        } else {
            logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
            return false;
        }
    }

    @Override
    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
        // Check if the isolation type of the physical network is BCF_SEGMENT, then delegate GuestNetworkGuru to design
        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
        if (physnet == null || physnet.getIsolationMethods() == null || !physnet.getIsolationMethods().contains("BCF_SEGMENT")) {
            logger.debug("Refusing to design this network, the physical isolation type is not BCF_SEGMENT");
            return null;
        }

        List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listByPhysicalNetwork(physnet.getId());
        if (devices.isEmpty()) {
            logger.error("No BigSwitch Controller on physical network " + physnet.getName());
            return null;
        }
        for (BigSwitchBcfDeviceVO d: devices){
            logger.debug("BigSwitch Controller " + d.getUuid()
                    + " found on physical network " + physnet.getId());
        }

        logger.debug("Physical isolation type is BCF_SEGMENT, asking GuestNetworkGuru to design this network");
        NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, name, vpcId, owner);
        if (networkObject == null) {
            return null;
        }
        // Override the broadcast domain type
        networkObject.setBroadcastDomainType(BroadcastDomainType.Vlan);

        return networkObject;
    }

    @Override
    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
        throws InsufficientVirtualNetworkCapacityException {
        assert (network.getState() == State.Implementing) : "Why are we implementing " + network;

        bcfUtilsInit();

        long dcId = dest.getDataCenter().getId();

        long physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());

        NetworkVO implemented =
            new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
                network.getDataCenterId(), physicalNetworkId, false);

        if (network.getGateway() != null) {
            implemented.setGateway(network.getGateway());
        }

        if (network.getCidr() != null) {
            implemented.setCidr(network.getCidr());
        }

        String vnetId = "";
        if (network.getBroadcastUri() == null) {
            vnetId = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), context.getReservationId(), UseSystemGuestVlans.valueIn(network.getAccountId()));
            if (vnetId == null) {
                throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " +
                        "part of network " + network + " implement ", DataCenter.class, dcId);
            }
            implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnetId));
            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(),
                    EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnetId + " Network Id: " + network.getId(), network.getId(), ApiCommandResourceType.Network.toString(), 0);
        } else {
            implemented.setBroadcastUri(network.getBroadcastUri());
        }

        // Name is either the given name or the uuid
        String name = network.getName();
        if (name == null || name.isEmpty()) {
            name = ((NetworkVO)network).getUuid();
        }
        if (name.length() > 64) {
            name = name.substring(0, 63); // max length 64
        }

        // update fields in network object
        NetworkVO networkObject = (NetworkVO) network;

        // determine whether this is VPC network or stand-alone network
        Vpc vpc = null;
        if(network.getVpcId()!=null){
            vpc = _vpcDao.acquireInLockTable(network.getVpcId());
        }

        // use uuid of networkVO as network id in BSN
        String networkId = networkObject.getUuid();

        String tenantId;
        String tenantName;
        if (vpc != null) {
            tenantId = vpc.getUuid();
            tenantName = vpc.getName();
            _vpcDao.releaseFromLockTable(vpc.getId());
        } else {
            // use network in CS as tenant in BSN
            // for non-VPC networks, use network name and id as tenant name and id
            tenantId = networkId;
            tenantName = name;
        }

        // store tenantId in networkObject for NetworkOrchestrator implementNetwork use
        networkObject.setNetworkDomain(tenantId);
        // store tenant Id in implemented object for future actions (e.g., shutdown)
        implemented.setNetworkDomain(tenantId);
        String vlanStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());

        // get public net info - needed to set up source nat gateway
        NetworkVO pubNet = _bcfUtils.getPublicNetwork(physicalNetworkId);

        // locate subnet info
        SearchCriteria<VlanVO> sc = _vlanDao.createSearchCriteria();
        sc.setParameters("network_id", pubNet.getId());
        VlanVO pubVlanVO = _vlanDao.findOneBy(sc);
        String pubVlanStr = pubVlanVO.getVlanTag();

        Integer vlan;
        if(StringUtils.isNumeric(vlanStr)){
            vlan = Integer.valueOf(vlanStr);
        } else {
            vlan = 0;
        }
        CreateBcfSegmentCommand cmd1 = new CreateBcfSegmentCommand(tenantId, tenantName, networkId, name, vlan);

        _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd1, networkObject);

        if(_bcfUtils.isNatEnabled()){
            Integer pvlan;
            if(StringUtils.isNumeric(pubVlanStr)){
                pvlan = Integer.valueOf(pubVlanStr);
            } else {
                pvlan = 0;
            }
            CreateBcfSegmentCommand cmd2 = new CreateBcfSegmentCommand("external", "external", "external", "external", pvlan);

            _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd2, networkObject);

            CreateBcfRouterCommand cmd3 = new CreateBcfRouterCommand(tenantId);

            _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd3, network);

            CreateBcfRouterInterfaceCommand cmd5 = new CreateBcfRouterInterfaceCommand(tenantId, network.getUuid(), network.getCidr(),
                    network.getGateway(), network.getName());

            _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd5, network);
        }
        return implemented;
    }



    @Override
    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
        // Have GuestNetworkGuru reserve for us
        super.reserve(nic, network, vm, dest, context);
    }

    @Override
    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
        return super.release(nic, vm, reservationId);
    }

    @Override
    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
        NetworkVO networkObject = _networkDao.findById(profile.getId());
        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vlan || networkObject.getBroadcastUri() == null) {
            logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
            return;
        }

        bcfUtilsInit();

        // tenantId stored in network domain field at creation
        String tenantId = networkObject.getNetworkDomain();

        String networkId = networkObject.getUuid();

        DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand(tenantId, networkId);

        _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, networkObject);

        super.shutdown(profile, offering);
    }

    @Override
    public boolean trash(Network network, NetworkOffering offering) {
        return super.trash(network, offering);
    }

    @Override
    public boolean prepareMigration(NicProfile nic, Network network,
            VirtualMachineProfile vm, DeployDestination dest,
            ReservationContext context) {
        bcfUtilsInit();

        // get arguments for CreateBcfAttachmentCommand
        // determine whether this is VPC network or stand-alone network
        Vpc vpc = null;
        if(network.getVpcId()!=null){
            vpc = _vpcDao.acquireInLockTable(network.getVpcId());
        }

        String networkId = network.getUuid();

        String tenantId;
        String tenantName;
        if (vpc != null) {
            tenantId = vpc.getUuid();
            tenantName = vpc.getName();
            boolean released = _vpcDao.releaseFromLockTable(vpc.getId());
            logger.debug("BCF guru release lock vpc id: " + vpc.getId()
                    + " released? " + released);
        } else {
            // use network id in CS as tenant in BSN
            // use network uuid as tenant id for non-VPC networks
            tenantId = networkId;
            tenantName = network.getName();
        }

        String hostname = dest.getHost().getName();
        long zoneId = network.getDataCenterId();
        String vmwareVswitchLabel = _networkModel.getDefaultGuestTrafficLabel(zoneId, HypervisorType.VMware);
        String[] labelArray = null;
        String vswitchName = null;
        if(vmwareVswitchLabel!=null){
            labelArray=vmwareVswitchLabel.split(",");
            vswitchName = labelArray[0];
        }

        // hypervisor type:
        //   kvm: ivs port name
        //   vmware: specific portgroup naming convention
        String pgName = "";
        if (dest.getHost().getHypervisorType() == HypervisorType.KVM){
            pgName = hostname;
        } else if (dest.getHost().getHypervisorType() == HypervisorType.VMware){
            pgName = hostname + "-" + vswitchName;
        }

        String nicId = nic.getUuid();
        Integer vlan = Integer.valueOf(BroadcastDomainType.getValue(nic.getIsolationUri()));
        String ipv4 = nic.getIPv4Address();
        String mac = nic.getMacAddress();

        CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand(tenantId,
                tenantName, networkId, pgName, nicId, vlan, ipv4, mac);

        _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);

        return true;
    }

    @Override
    public void rollbackMigration(NicProfile nic, Network network,
            VirtualMachineProfile vm, ReservationContext src,
            ReservationContext dst) {
        logger.debug("BCF guru rollback migration");
    }

    @Override
    public void commitMigration(NicProfile nic, Network network,
            VirtualMachineProfile vm, ReservationContext src,
            ReservationContext dst) {
        logger.debug("BCF guru commit migration");
    }

    private void bcfUtilsInit(){
        if (_bcfUtils == null) {
            _bcfUtils = new BigSwitchBcfUtils(_networkDao, _nicDao,
                    _vmDao, _hostDao, _vpcDao, _bigswitchBcfDao,
                    _agentMgr, _vlanDao, _ipAddressDao, _fwRulesDao,
                    _fwCidrsDao, _aclItemDao, _aclItemCidrsDao, _networkModel);
        }
    }
}
