/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.pim.impl;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.mcast.MulticastRouteService;
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;

import java.util.Optional;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * The main PIM controller class.
 */
@Component(immediate = true)
public class PimApplication {
    private final Logger log = getLogger(getClass());

    // Used to get the appId
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    // Register to receive PIM packets, used to send packets as well
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PacketService packetService;

    // Use the MulticastRouteService to manage incoming PIM Join/Prune state as well as
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected MulticastRouteService ms;

    // Create an instance of the PIM packet handler
    protected PimPacketHandler pimPacketHandler;

    // Provide interfaces to the pimInterface manager as a result of Netconfig updates.
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PimInterfaceService pimInterfaceManager;

    private final PimPacketProcessor processor = new PimPacketProcessor();

    /**
     * Activate the PIM component.
     */
    @Activate
    public void activate() {
        // Get our application ID
        ApplicationId appId = coreService.registerApplication("org.onosproject.pim");

        // Build the traffic selector for PIM packets
        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        selector.matchEthType(Ethernet.TYPE_IPV4);
        selector.matchIPProtocol(IPv4.PROTOCOL_PIM);

        // Use the traffic selector to tell the packet service which packets we want.
        packetService.addProcessor(processor, PacketProcessor.director(5));

        packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
                appId, Optional.empty());

        // Get a copy of the PIM Packet Handler
        pimPacketHandler = new PimPacketHandler();

        log.info("Started");
    }

    /**
     * Deactivate the PIM component.
     */
    @Deactivate
    public void deactivate() {
        packetService.removeProcessor(processor);

        log.info("Stopped");
    }

    /**
     * The class that will receive PIM packets, sanitize them, determine the PIMInterface
     * they arrived on, then forward them on to be processed by the appropriate entity.
     */
    public class PimPacketProcessor implements PacketProcessor {

        @Override
        public void process(PacketContext context) {

            // return if this packet has already been handled
            if (context.isHandled()) {
                return;
            }

            // get the inbound packet
            InboundPacket pkt = context.inPacket();
            if (pkt == null) {
                // problem getting the inbound pkt.  Log it debug to avoid spamming log file
                log.debug("Could not retrieve packet from context");
                return;
            }

            // Get the ethernet header
            Ethernet eth = pkt.parsed();
            if (eth == null) {
                // problem getting the ethernet pkt.  Log it debug to avoid spamming log file
                log.debug("Could not retrieve ethernet packet from the parsed packet");
                return;
            }

            // Get the PIM Interface the packet was received on.
            PimInterface pimi = pimInterfaceManager.getPimInterface(pkt.receivedFrom());
            if (pimi == null) {
                return;
            }

            /*
             * Pass the packet processing off to the PIMInterface for processing.
             *
             * TODO: Is it possible that PIM interface processing should move to the
             * PIMInterfaceManager directly?
             */
            pimPacketHandler.processPacket(eth, pimi);
        }
    }

}
