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

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.NshServicePathId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.ExtensionSelectorResolver;
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.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.ExtensionSelector;
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.HostService;
import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
import org.onosproject.vtnrsc.portchain.PortChainService;
import org.onosproject.vtnrsc.portpair.PortPairService;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;

import java.util.List;
import java.util.ListIterator;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provides Service Function Forwarder implementation.
 */
@Component(immediate = true)
@Service
public class ServiceFunctionForwarderImpl implements ServiceFunctionForwarderService {

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DriverService driverService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualPortService virtualPortService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VtnRscService vtnRscService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortPairService portPairService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortPairGroupService portPairGroupService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowClassifierService flowClassifierService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortChainService portChainService;

    private final Logger log = getLogger(getClass());
    protected ApplicationId appId;
    protected FlowObjectiveService flowObjectiveService;

    private static final String DRIVER_NAME = "onosfw";
    private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null";
    private static final String PORT_CHAIN_ID_NOT_NULL = "Port-Chain-Id cannot be null";
    private static final String APP_ID_NOT_NULL = "Application-Id cannot be null";
    private static final int NULL = 0;

    /**
     * Default constructor.
     */
    public ServiceFunctionForwarderImpl() {
    }

    /**
     * Explicit constructor.
     *
     * @param appId Application id
     */
    public ServiceFunctionForwarderImpl(ApplicationId appId) {
        this.appId = checkNotNull(appId, APP_ID_NOT_NULL);
        ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
        this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
    }

    @Override
    public void installForwardingRule(PortChain portChain, NshServicePathId nshSpi) {
        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
        prepareServiceFunctionForwarder(portChain, nshSpi, Objective.Operation.ADD);
    }

    @Override
    public void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSpi) {
        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
        prepareServiceFunctionForwarder(portChain, nshSpi, Objective.Operation.REMOVE);
    }

    @Override
    public void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSpi,
                                                Objective.Operation type) {

        // Go through the port pair group list
        List<PortPairGroupId> portPairGrpList = portChain.portPairGroups();
        ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator();

        // Get source port pair group
        if (!listGrpIterator.hasNext()) {
            return;
        }
        PortPairGroupId portPairGrpId = listGrpIterator.next();
        PortPairGroup currentPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);

        // Get destination port pair group
        if (!listGrpIterator.hasNext()) {
            return;
        }
        portPairGrpId = listGrpIterator.next();
        PortPairGroup nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);

        // push SFF to OVS
        pushServiceFunctionForwarder(currentPortPairGroup, nextPortPairGroup, listGrpIterator, nshSpi, type);
    }

    /**
     * Push service-function-forwarder to OVS.
     *
     * @param currentPortPairGroup current port-pair-group
     * @param nextPortPairGroup next port-pair-group
     * @param listGrpIterator pointer to port-pair-group list
     * @param nshSpi nsh service path id
     * @param type objective type
     */
    public void pushServiceFunctionForwarder(PortPairGroup currentPortPairGroup, PortPairGroup nextPortPairGroup,
            ListIterator<PortPairGroupId> listGrpIterator, NshServicePathId nshSpi, Objective.Operation type) {
        DeviceId deviceId = null;
        DeviceId currentDeviceId = null;
        DeviceId nextDeviceId = null;
        PortPairGroupId portPairGrpId = null;

        // Travel from SF to SF.
        do {
            // Get the required information on port pairs from source port pair
            // group
            List<PortPairId> portPairList = currentPortPairGroup.portPairs();
            ListIterator<PortPairId> portPLIterator = portPairList.listIterator();
            if (!portPLIterator.hasNext()) {
                break;
            }

            PortPairId portPairId = portPLIterator.next();
            PortPair portPair = portPairService.getPortPair(portPairId);

            currentDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));
            if (deviceId == null) {
                deviceId = currentDeviceId;
            }

            // pack traffic selector
            TrafficSelector.Builder selector = packTrafficSelector(deviceId, portPair, nshSpi);

            // Get the required information on port pairs from destination port
            // pair group
            portPairList = nextPortPairGroup.portPairs();
            portPLIterator = portPairList.listIterator();
            if (!portPLIterator.hasNext()) {
                break;
            }

            portPairId = portPLIterator.next();
            portPair = portPairService.getPortPair(portPairId);

            nextDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));

            // pack traffic treatment
            TrafficTreatment.Builder treatment = packTrafficTreatment(currentDeviceId, nextDeviceId, portPair);

            // Send SFF to OVS
            sendServiceFunctionForwarder(selector, treatment, deviceId, type);

            // Replace source port pair group with destination port pair group
            // for moving to next SFF processing.
            currentPortPairGroup = nextPortPairGroup;
            if (!listGrpIterator.hasNext()) {
                break;
            }
            portPairGrpId = listGrpIterator.next();
            nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
        } while (true);
    }

    /**
     * Pack Traffic selector.
     *
     * @param deviceId device id
     * @param portPair port-pair
     * @param nshSpi nsh spi
     * @return traffic treatment
     */
    public TrafficSelector.Builder packTrafficSelector(DeviceId deviceId, PortPair portPair, NshServicePathId nshSpi) {
        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        MacAddress dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
        Host host = hostService.getHost(HostId.hostId(dstMacAddress));
        PortNumber port = host.location().port();
        selector.matchInPort(port);

        DriverHandler handler = driverService.createHandler(deviceId);
        ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class);
        ExtensionSelector nspSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());

        try {
            nspSpiSelector.setPropertyValue("nshSpi", nshSpi);
        } catch (Exception e) {
            log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId);
        }

        selector.extension(nspSpiSelector, deviceId);

        return selector;
    }

    /**
     * Pack Traffic treatment.
     *
     * @param currentDeviceId current device id
     * @param nextDeviceId next device id
     * @param portPair port-pair
     * @return traffic treatment
     */
    public TrafficTreatment.Builder packTrafficTreatment(DeviceId currentDeviceId, DeviceId nextDeviceId,
            PortPair portPair) {
        MacAddress srcMacAddress = null;

        // Check the treatment whether destination SF is on same OVS or in
        // different OVS.
        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
        if (currentDeviceId.equals(nextDeviceId)) {
            srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();

            Host host = hostService.getHost(HostId.hostId(srcMacAddress));
            PortNumber port = host.location().port();
            treatment.setOutput(port);
        } else {
            VlanId vlanId = VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(portPair.tenantId()).toString())));
            treatment.setVlanId(vlanId);
        }

        return treatment;
    }

    /**
     * Send service function forwarder to OVS.
     *
     * @param selector traffic selector
     * @param treatment traffic treatment
     * @param deviceId device id
     * @param type operation type
     */
    public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment,
            DeviceId deviceId, Objective.Operation type) {
        ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build())
                .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE);
        if (type.equals(Objective.Operation.ADD)) {
            log.debug("ADD");
            flowObjectiveService.forward(deviceId, objective.add());
        } else {
            log.debug("REMOVE");
            flowObjectiveService.forward(deviceId, objective.remove());
        }
    }
}
