/*
 * 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.ADVISOR_MAX + 6);

        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        // Only IPv4 is supported in current vBNG.
        selector.matchEthType(Ethernet.TYPE_ARP);
        packetService.requestPackets(selector.build(),
                                   PacketPriority.REACTIVE, appId);

        log.info("vBNG virtual public hosts started");
    }

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

    /**
     * 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())));
        }
    }
}
