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

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
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.Ethernet;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;

@Component(immediate = true)
@Service(value = org.onosproject.mfwd.impl.McastIntentManager.class)
public class McastIntentManager {

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected IntentService intentService;

    private static McastIntentManager instance;

    public McastIntentManager() {
        instance = this;
    }

    /**
     * Active this component.
     */
    @Activate
    public void activate() { }

    /**
     * Deactivate this component.
     */
    @Deactivate
    public void deactivate() {
        withdrawAllIntents();
    }

    /**
     * Get instance of this intentManager.
     *
     * @return the instance of this intent manager.
     */
    public static McastIntentManager getInstance() {
        if (instance == null) {
            instance = new McastIntentManager();
        }
        return instance;
    }

    /**
     * Install the PointToMultipoint forwarding intent.
     *
     * @param mroute multicast route entry
     * @return the intent that has been set or null otherwise
     */
    public SinglePointToMultiPointIntent setIntent(McastRoute mroute) {
        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();

        if (mroute.getIngressPoint() == null) {
            return null;
        }

        /*
         * Match the group AND source addresses.  We will also check ether type to
         * determine if we are doing ipv4 or ipv6.
         *
         * If we really wanted to be pendantic we could put in a
         * condition to make sure the ethernet MAC address was also
         * mcast.
         */
        selector.matchEthType(Ethernet.TYPE_IPV4)
                .matchIPDst(mroute.getGaddr())
                .matchIPSrc(mroute.getSaddr());


        SinglePointToMultiPointIntent.Builder builder =  SinglePointToMultiPointIntent.builder()
                        .appId(McastForwarding.getAppId())
                        .selector(selector.build())
                        .treatment(treatment)
                        .ingressPoint(mroute.getIngressPoint().getConnectPoint());

        // allowing intent to be pushed without egress points means we can drop packets.
        if (!mroute.getEgressPoints().isEmpty()) {
            builder.egressPoints(mroute.getEgressConnectPoints());
        }

        SinglePointToMultiPointIntent intent = builder.build();
        intentService.submit(intent);
        mroute.setDirty(false);

        return intent;
    }

    /**
     * Withdraw the intent represented by this route.
     *
     * @param mroute the mcast route whose intent we want to remove
     */
    public void withdrawIntent(McastRoute mroute) {
        Intent intent = intentService.getIntent(mroute.getIntentKey());
        intentService.withdraw(intent);
        mroute.setDirty(false);
    }

    /**
     * Withdraw all intents.
     *
     * This will be called from the deactivate method so we don't leave
     * a mess behind us after we leave.
     */
    public void withdrawAllIntents() {
        for (Intent intent : intentService.getIntents()) {
            intentService.withdraw(intent);
        }
    }
}
