/*
 * 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.virtualbng;

import static org.slf4j.LoggerFactory.getLogger;

import java.nio.ByteBuffer;

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.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.slf4j.Logger;

/**
 * When the upstream gateway which is outside local SDN network wants to send
 * packets to our local public IP addresses, it will send out ARP requests to
 * get the MAC address of each public IP address. Actually, there are no hosts
 * configured with those public IP addresses, so this class is to emulate the
 * behavior of the non-existed hosts and return ARP replies.
 * <p>
 * Since we will rewrite the destination MAC address in the switch before
 * traffic packets go to the destination, so the MAC address can be any number.
 * We manually configured a random MAC address for this purpose in the vBNG
 * configuration file.
 * </p>
 */
@Component(immediate = true)
public class VirtualPublicHosts {
    private final Logger log = getLogger(getClass());

    private static final String APP_NAME =
            "org.onosproject.virtualbng.VirtualPublicHosts";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VbngConfigurationService vbngConfigService;

    private ApplicationId appId;
    private ArpRequestProcessor processor = new ArpRequestProcessor();

    @Activate
    public void activate() {
        appId = coreService.registerApplication(APP_NAME);

        packetService.addProcessor(processor, PacketProcessor.director(6));
        requestIntercepts();
        log.info("vBNG virtual public hosts started");
    }

    @Deactivate
    public void deactivate() {
        withdrawIntercepts();
        packetService.removeProcessor(processor);
        processor = null;
        log.info("vBNG virtual public hosts Stopped");
    }

    /**
     * Request packet in via PacketService.
     */
    private void requestIntercepts() {
        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        // Only IPv4 is supported in current vBNG.
        selector.matchEthType(Ethernet.TYPE_ARP);
        packetService.requestPackets(selector.build(),
                                     PacketPriority.REACTIVE, appId);
    }

    /**
     * Cancel request for packet in via PacketService.
     */
    private void withdrawIntercepts() {
        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        // Only IPv4 is supported in current vBNG.
        selector.matchEthType(Ethernet.TYPE_ARP);
        packetService.cancelPackets(selector.build(),
                                    PacketPriority.REACTIVE, appId);
    }

    /**
     * This class filters out the ARP request packets, generates the ARP
     * reply packets, and emits those packets.
     */
    private class ArpRequestProcessor implements PacketProcessor {
        @Override
        public void process(PacketContext context) {

            InboundPacket pkt = context.inPacket();
            Ethernet ethPkt = pkt.parsed();

            // Only handle the ARP packets
            if (ethPkt == null || ethPkt.getEtherType() != Ethernet.TYPE_ARP) {
                return;
            }
            ARP arpPacket = (ARP) ethPkt.getPayload();
            // Only handle ARP request packets
            if (arpPacket.getOpCode() != ARP.OP_REQUEST) {
                return;
            }

            Ip4Address targetIpAddress = Ip4Address
                    .valueOf(arpPacket.getTargetProtocolAddress());

            // Only handle an ARP request when the target IP address inside is
            // an assigned public IP address
            if (!vbngConfigService.isAssignedPublicIpAddress(targetIpAddress)) {
                return;
            }

            MacAddress virtualHostMac =
                    vbngConfigService.getPublicFacingMac();
            if (virtualHostMac == null) {
                return;
            }

            ConnectPoint srcConnectPoint = pkt.receivedFrom();
            Ethernet eth = ARP.buildArpReply(targetIpAddress,
                                             virtualHostMac,
                                             ethPkt);

            TrafficTreatment.Builder builder =
                    DefaultTrafficTreatment.builder();
            builder.setOutput(srcConnectPoint.port());
            packetService.emit(new DefaultOutboundPacket(
                    srcConnectPoint.deviceId(),
                    builder.build(),
                    ByteBuffer.wrap(eth.serialize())));
        }
    }
}
