/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.vtn.impl;

import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.DefaultTunnelDescription;
import org.onosproject.net.behaviour.IpTunnelEndPoint;
import org.onosproject.net.behaviour.TunnelConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.behaviour.TunnelEndPoint;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtn.VTNService;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;

import com.google.common.collect.Sets;

/**
 * Provides implementation of VTNService.
 */
@Component(immediate = true)
@Service
public class VTNManager implements VTNService {
    private final Logger log = getLogger(getClass());

    private static final String APP_ID = "org.onosproject.app.vtn";
    private ScheduledExecutorService backgroundService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowRuleService flowRuleService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService storageService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TenantNetworkService tenantNetworkService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualPortService virtualPortService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DriverService driverService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowObjectiveService flowObjectiveService;
    private EventuallyConsistentMap<HostId, SegmentationId> binding;
    private ApplicationId appId;
    private HostListener hostListener = new InnerHostListener();
    private DeviceListener deviceListener = new InnerDeviceListener();
    private static final String IFACEID = "ifaceid";
    private static final String PORT_HEAD = "vxlan";
    private static final String DEFAULT_BRIDGE_NAME = "br-int";
    private static final String CONTROLLER_IP_KEY = "ipaddress";
    private static final int DEFAULT_MAC_PRIORITY = 0x0000;
    private static final int MAC_PRIORITY = 0xffff;
    private static final int DEFAULT_PORT_PRIORITY = 0x0000;
    private static final int PORT_PRIORITY = 0xffff;
    private static final String SWITCH_CHANNEL_ID = "channelId";

    @Activate
    public void activate() {
        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                .register(KryoNamespaces.API);
        appId = coreService.registerApplication(APP_ID);
        deviceService.addListener(deviceListener);
        hostService.addListener(hostListener);
        backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos-apps/vtn",
                                                                            "manager-background"));
        binding = storageService
                .<HostId, SegmentationId>eventuallyConsistentMapBuilder()
                .withName("all_tunnel").withSerializer(serializer)
                .withTimestampProvider((k, v) -> new WallClockTimestamp())
                .build();
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        backgroundService.shutdown();
        binding.destroy();
        log.info("Stopped");
    }

    @Override
    public void onServerDetected(Device device) {
        Iterable<Device> devices = deviceService.getAvailableDevices();
        DriverHandler handler = driverService.createHandler(device.id());
        BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
        bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME));
        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
        IpAddress ip = IpAddress.valueOf(ipAddress);
        Sets.newHashSet(devices).stream()
                .filter(d -> Device.Type.CONTROLLER == d.type())
                .filter(d -> !device.id().equals(d.id())).forEach(d -> {
                    if (!device.id().equals(d.id())
                            && Device.Type.CONTROLLER == d.type()) {
                        String ipAddress1 = d.annotations()
                                .value(CONTROLLER_IP_KEY);
                        IpAddress ip1 = IpAddress.valueOf(ipAddress1);
                        applyTunnelConfig(ip, ip1, handler);
                        DriverHandler handler1 = driverService
                                .createHandler(d.id());
                        applyTunnelConfig(ip1, ip, handler1);
                    }
                });
    }

    @Override
    public void onServerVanished(Device device) {
        Iterable<Device> devices = deviceService.getAvailableDevices();
        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
        IpAddress dst = IpAddress.valueOf(ipAddress);
        Sets.newHashSet(devices).stream()
                .filter(d -> d.type() == Device.Type.CONTROLLER)
                .filter(d -> !device.id().equals(d.id())).forEach(d -> {
                    String ipAddress1 = d.annotations()
                            .value(CONTROLLER_IP_KEY);
                    DriverHandler handler = driverService.createHandler(d.id());
                    IpAddress src = IpAddress.valueOf(ipAddress1);
                    removeTunnelConfig(src, dst, handler);
                });
    }

    private void applyTunnelConfig(IpAddress src, IpAddress dst,
                                   DriverHandler handler) {
        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
        TunnelDescription tunnel = new DefaultTunnelDescription(
                                                                tunnelAsSrc,
                                                                tunnelAsDst,
                                                                TunnelDescription.Type.VXLAN,
                                                                null);
        TunnelConfig config = handler.behaviour(TunnelConfig.class);
        config.createTunnel(tunnel);
    }

    private void removeTunnelConfig(IpAddress src, IpAddress dst,
                                    DriverHandler handler) {
        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
        TunnelDescription tunnel = new DefaultTunnelDescription(
                                                                tunnelAsSrc,
                                                                tunnelAsDst,
                                                                TunnelDescription.Type.VXLAN,
                                                                null);
        TunnelConfig config = handler.behaviour(TunnelConfig.class);
        config.removeTunnel(tunnel);
    }

    @Override
    public void onOvsDetected(Device device) {
        programMacDefaultRules(device.id(), appId, Objective.Operation.ADD);
        programPortDefaultRules(device.id(), appId, Objective.Operation.ADD);
        Set<Host> hosts = hostService.getConnectedHosts(device.id());
        hosts.forEach(h -> {
            String ifaceId = h.annotations().value(IFACEID);
            String currentControllerIp = getControllerIpOfSwitch(device.id());
            VirtualPortId portId = VirtualPortId.portId(ifaceId);
            VirtualPort port = virtualPortService.getPort(portId);
            TenantNetwork network = tenantNetworkService
                    .getNetwork(port.networkId());
            String vxlanName = "vxlan-" + currentControllerIp;

            DriverHandler handler = driverService.createHandler(device.id());
            BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
            Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
                    .getBridges();
            Iterator<BridgeDescription> it = bridgeDescriptions.iterator();
            if (it.hasNext()) {
                BridgeDescription sw = it.next();
                Set<PortNumber> ports = bridgeConfig.getPortNumbers();
                ports.stream().filter(p -> p.name().equalsIgnoreCase(vxlanName))
                        .forEach(p -> {
                    programTunnelOut(sw.deviceId(), network.segmentationId(), p,
                                     h.mac(), appId, Objective.Operation.ADD);
                });
            }

        });
    }

    @Override
    public void onOvsVanished(Device device) {
        programMacDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
        programPortDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
    }

    @Override
    public void onHostDetected(Host host) {
        String ifaceId = host.annotations().value(IFACEID);
        DeviceId deviceId = host.location().deviceId();
        String currentControllerIp = getControllerIpOfSwitch(deviceId);
        Iterable<Device> devices = deviceService.getAvailableDevices();
        VirtualPortId portId = VirtualPortId.portId(ifaceId);
        VirtualPort port = virtualPortService.getPort(portId);
        TenantNetwork network = tenantNetworkService
                .getNetwork(port.networkId());
        String tunnelName = "vxlan-" + currentControllerIp;
        binding.put(host.id(), network.segmentationId());
        List<Port> allPorts = deviceService.getPorts(deviceId);
        PortNumber inPort = host.location().port();
        Set<Port> localPorts = new HashSet<>();
        Set<Port> tunnelPorts = new HashSet<>();
        List<Port> outports = new ArrayList<>();
        Sets.newHashSet(allPorts.iterator()).stream()
        .filter(p -> !p.number().equals(PortNumber.LOCAL)).forEach(p -> {
            if (!p.annotations().value("portName").startsWith(PORT_HEAD)) {
                localPorts.add(p);
            } else {
                tunnelPorts.add(p);
            }
            outports.add(p);
        });

        programLocalBcastRules(deviceId, network.segmentationId(), inPort,
                               outports, appId, Objective.Operation.ADD);
        programLocalOut(deviceId, network.segmentationId(), inPort, host.mac(),
                        appId, Objective.Operation.ADD);
        tunnelPorts
                .forEach(tp -> programTunnelFloodOut(deviceId,
                                                     network.segmentationId(),
                                                     tp.number(), localPorts,
                                                     appId,
                                                     Objective.Operation.ADD));
        Sets.newHashSet(devices).stream()
                .filter(d -> d.type() == Device.Type.CONTROLLER).forEach(d -> {
                    DriverHandler handler = driverService.createHandler(d.id());
                    BridgeConfig bridgeConfig = handler
                            .behaviour(BridgeConfig.class);
                    Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
                            .getBridges();

                    Iterator<BridgeDescription> it = bridgeDescriptions
                            .iterator();
                    if (it.hasNext()) {
                        BridgeDescription sw = it.next();
                        Set<PortNumber> ports = bridgeConfig.getPortNumbers();
                        ports.stream()
                                .filter(p -> p.name()
                                        .equalsIgnoreCase(tunnelName))
                                .forEach(p -> {
                            programTunnelOut(sw.deviceId(),
                                             network.segmentationId(), p,
                                             host.mac(), appId,
                                             Objective.Operation.ADD);
                        });
                    }
                });
        programLocalIn(deviceId, network.segmentationId(), inPort, host.mac(),
                       appId, Objective.Operation.ADD);
        tunnelPorts
                .forEach(tp -> programTunnelIn(deviceId,
                                               network.segmentationId(),
                                               tp.number(), inPort, host.mac(),
                                               appId, Objective.Operation.ADD));

    }

    @Override
    public void onHostVanished(Host host) {
        SegmentationId segId = binding.remove(host.id());
        DeviceId deviceId = host.location().deviceId();
        String currentControllerIp = getControllerIpOfSwitch(deviceId);
        Iterable<Device> devices = deviceService.getAvailableDevices();
        List<Port> allPorts = deviceService.getPorts(deviceId);
        PortNumber inPort = host.location().port();
        String vxlanName = "vxlan-" + currentControllerIp;
        Set<Port> localPorts = new HashSet<>();
        Set<Port> tunnelPorts = new HashSet<>();
        List<Port> outports = new ArrayList<>();
        Sets.newHashSet(allPorts.iterator()).stream()
        .filter(p -> !p.number().equals(PortNumber.LOCAL)).forEach(p -> {
            if (!p.annotations().value("portName").startsWith(PORT_HEAD)) {
                localPorts.add(p);
            } else {
                tunnelPorts.add(p);
            }
            outports.add(p);
        });

        programLocalBcastRules(deviceId, segId, inPort,
                               outports, appId, Objective.Operation.REMOVE);
        programLocalOut(deviceId, segId, inPort, host.mac(),
                        appId, Objective.Operation.REMOVE);
        tunnelPorts
                .forEach(tp -> programTunnelFloodOut(deviceId,
                                                     segId,
                                                     tp.number(), localPorts,
                                                     appId,
                                                     Objective.Operation.REMOVE));
        Sets.newHashSet(devices).stream()
                .filter(d -> d.type() == Device.Type.CONTROLLER).forEach(d -> {
                    DriverHandler handler = driverService.createHandler(d.id());
                    BridgeConfig bridgeConfig = handler
                            .behaviour(BridgeConfig.class);
                    Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
                            .getBridges();

                    Iterator<BridgeDescription> it = bridgeDescriptions
                            .iterator();
                    if (it.hasNext()) {
                        BridgeDescription sw = it.next();
                        Set<PortNumber> ports = bridgeConfig.getPortNumbers();
                        ports.stream()
                                .filter(p -> p.name()
                                        .equalsIgnoreCase(vxlanName))
                                .forEach(p -> {
                            programTunnelOut(sw.deviceId(),
                                             segId, p,
                                             host.mac(), appId,
                                             Objective.Operation.REMOVE);
                        });
                    }
                });
        programLocalIn(deviceId, segId, inPort, host.mac(),
                       appId, Objective.Operation.REMOVE);
        tunnelPorts
                .forEach(tp -> programTunnelIn(deviceId,
                                               segId,
                                               tp.number(), inPort, host.mac(),
                                               appId, Objective.Operation.REMOVE));
    }

    private class InnerDeviceListener implements DeviceListener {

        @Override
        public void event(DeviceEvent event) {
            Device device = event.subject();
            if (Device.Type.CONTROLLER == device.type()
                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
                backgroundService.execute(() -> {
                    onServerDetected(device);
                });
            } else if (Device.Type.CONTROLLER == device.type()
                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
                            .type()) {
                backgroundService.execute(() -> {
                    onServerVanished(device);
                });
            } else if (Device.Type.SWITCH == device.type()
                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
                backgroundService.execute(() -> {
                    onOvsDetected(device);
                });
            } else if (Device.Type.SWITCH == device.type()
                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
                            .type()) {
                backgroundService.execute(() -> {
                    onOvsVanished(device);
                });
            } else {
                log.info("Do nothing for this device type");
            }
        }

    }

    private class InnerHostListener implements HostListener {

        @Override
        public void event(HostEvent event) {
            Host host = event.subject();
            if (HostEvent.Type.HOST_ADDED == event.type()) {
                backgroundService.execute(() -> {
                    onHostDetected(host);
                });
            } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
                backgroundService.execute(() -> {
                    onHostVanished(host);
                });
            } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
                backgroundService.execute(() -> {
                    onHostVanished(host);
                    onHostDetected(host);
                });
            }
        }

    }

    // Used to forward the flows to the local VM.
    private void programLocalOut(DeviceId dpid, SegmentationId segmentationId,
                                 PortNumber outPort, MacAddress sourceMac,
                                 ApplicationId appid,
                                 Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchEthDst(sourceMac).build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                .add(Instructions
                        .modTunnelId(Long.parseLong(segmentationId.toString())))
                .setOutput(outPort).build();
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment).withSelector(selector)
                .fromApp(appId).withFlag(Flag.SPECIFIC)
                .withPriority(MAC_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }

    }

    // Used to forward the flows into the VXLAN tunnel.
    private void programTunnelOut(DeviceId dpid, SegmentationId segmentationId,
                                  PortNumber tunnelOutPort, MacAddress dstMac,
                                  ApplicationId appid,
                                  Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchEthDst(dstMac).add(Criteria.matchTunnelId(Long
                        .parseLong(segmentationId.toString())))
                .build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()

        .setOutput(tunnelOutPort).build();
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment).withSelector(selector)
                .fromApp(appId).withFlag(Flag.SPECIFIC)
                .withPriority(MAC_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }

    }

    // Used to forward multicast flows to remote VMs of the same tenant via
    // VXLAN tunnel.
    private void programTunnelFloodOut(DeviceId dpid,
                                       SegmentationId segmentationId,
                                       PortNumber ofPortOut,
                                       Iterable<Port> localports,
                                       ApplicationId appid,
                                       Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchInPort(ofPortOut)

                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
                             .toString()))).matchEthDst(MacAddress.BROADCAST)
                .build();
        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
        for (Port outport : localports) {
            treatment.setOutput(outport.number());
        }

        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment.build())
                .withSelector(selector).fromApp(appId).makePermanent()
                .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Applies default flows to mac table.
    private void programMacDefaultRules(DeviceId dpid, ApplicationId appid,
                                        Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder().build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder().drop()
                .build();
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment).withSelector(selector)
                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
                .withPriority(DEFAULT_MAC_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Used to forward the flows to the local VMs with the same tenant.
    private void programLocalBcastRules(DeviceId dpid,
                                        SegmentationId segmentationId,
                                        PortNumber inPort, List<Port> allports,
                                        ApplicationId appid,
                                        Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchInPort(inPort).matchEthDst(MacAddress.BROADCAST)
                .add(Criteria.matchTunnelId(Long
                        .parseLong(segmentationId.toString())))
                .build();
        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();

        for (Port outport : allports) {
            if (inPort != outport.number()) {
                treatment.setOutput(outport.number());
            }
        }
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment.build())
                .withSelector(selector).fromApp(appId).makePermanent()
                .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Used to apply local entry flow.
    private void programLocalIn(DeviceId dpid, SegmentationId segmentationId,
                                PortNumber inPort, MacAddress srcMac,
                                ApplicationId appid, Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchInPort(inPort).matchEthSrc(srcMac).build();
        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
        treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId
                .toString())));
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment.build())
                .withSelector(selector).fromApp(appId).makePermanent()
                .withFlag(Flag.SPECIFIC).withPriority(PORT_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Used to forward the flows from the egress tunnel to the VM.
    private void programTunnelIn(DeviceId dpid, SegmentationId segmentationId,
                                 PortNumber tunnelInPort, PortNumber outPort,
                                 MacAddress sourceMac, ApplicationId appid,
                                 Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchInPort(tunnelInPort).add(Criteria.matchTunnelId(Long
                        .parseLong(segmentationId.toString())))
                .build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();

        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment).withSelector(selector)
                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
                .withPriority(PORT_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Applies the default flows to port table.
    private void programPortDefaultRules(DeviceId dpid, ApplicationId appid,
                                         Objective.Operation type) {
        TrafficSelector selector = DefaultTrafficSelector.builder().build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
        ForwardingObjective.Builder objective = DefaultForwardingObjective
                .builder().withTreatment(treatment).withSelector(selector)
                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
                .withPriority(DEFAULT_PORT_PRIORITY);
        if (type.equals(Objective.Operation.ADD)) {
            flowObjectiveService.forward(dpid, objective.add());
        } else {
            flowObjectiveService.forward(dpid, objective.remove());
        }
    }

    // Used to get channelId from the device annotations.
    private String getControllerIpOfSwitch(DeviceId deviceId) {
        Device device = deviceService.getDevice(deviceId);
        String url = device.annotations().value(SWITCH_CHANNEL_ID);
        return url.substring(0, url.lastIndexOf(":"));
    }

}
