/*
 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * 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.opencord.olt.impl;

import org.onlab.packet.EthType;
import org.onlab.packet.IPv4;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleEvent;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.meter.MeterId;
import org.opencord.olt.OltFlowsStatus;
import org.opencord.sadis.UniTagInformation;

import java.util.concurrent.atomic.AtomicBoolean;

import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
import static org.opencord.olt.impl.OltFlowService.EAPOL_DEFAULT_VLAN;
import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_TP_ID_DEFAULT;

/**
 * Utility class for Flow service utility methods.
 */
public final class OltFlowServiceUtils {

    public static final int NONE_TP_ID = -1;

    private OltFlowServiceUtils() {
    }

    /**
     * Constructs and returns the metadata from cVlan, techProfileId and upstreamOltMeterId.
     *
     * @param cVlan                 the customer vlan
     * @param techProfileId         the technology profile
     * @param upstreamOltMeterId    the upstream olt meter id
     * @return Metadata
     */
    public static Long createTechProfValueForWriteMetadata(VlanId cVlan, int techProfileId,
                                                           MeterId upstreamOltMeterId) {
        Long writeMetadata;

        if (cVlan == null || VlanId.NONE.equals(cVlan)) {
            writeMetadata = (long) techProfileId << 32;
        } else {
            writeMetadata = ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
        }
        if (upstreamOltMeterId == null) {
            return writeMetadata;
        } else {
            return writeMetadata | upstreamOltMeterId.id();
        }
    }

    /**
     * Converts FlowRuleEvent.Type to OltFlowService.OltFlowsStatus.
     *
     * @param type FlowRuleEvent type
     * @return OltFlowService.OltFlowsStatus
     */
    public static OltFlowsStatus flowRuleStatusToOltFlowStatus(FlowRuleEvent.Type type) {
        switch (type) {
            case RULE_ADD_REQUESTED:
                return OltFlowsStatus.PENDING_ADD;
            case RULE_ADDED:
                return OltFlowsStatus.ADDED;
            case RULE_REMOVE_REQUESTED:
                return OltFlowsStatus.PENDING_REMOVE;
            case RULE_REMOVED:
                return OltFlowsStatus.REMOVED;
            default:
                return OltFlowsStatus.NONE;
        }
    }

    /**
     * Checks if the configured Mac address is valid for a UniTagInformation.
     *
     * @param tagInformation UniTagInformation
     * @return true if the mac address is valid
     */
    public static boolean isMacAddressValid(UniTagInformation tagInformation) {
        return tagInformation.getConfiguredMacAddress() != null &&
                !tagInformation.getConfiguredMacAddress().trim().equals("") &&
                !MacAddress.NONE.equals(MacAddress.valueOf(tagInformation.getConfiguredMacAddress()));
    }

    /**
     * Returns true if the flow is a DHCP flow.
     * Matches both upstream and downstream flows.
     *
     * @param flowRule The FlowRule to evaluate
     * @return boolean
     */
    public static boolean isDhcpFlow(FlowRule flowRule) {
        IPProtocolCriterion ipCriterion = (IPProtocolCriterion) flowRule.selector()
                .getCriterion(Criterion.Type.IP_PROTO);
        if (ipCriterion == null) {
            return false;
        }

        UdpPortCriterion src = (UdpPortCriterion) flowRule.selector().getCriterion(Criterion.Type.UDP_SRC);

        if (src == null) {
            return false;
        }
        return ipCriterion.protocol() == IPv4.PROTOCOL_UDP &&
                (src.udpPort().toInt() == 68 || src.udpPort().toInt() == 67);
    }

    /**
     * Returns true if the flow is a Pppoe flow.
     *
     * @param flowRule The FlowRule to evaluate
     * @return boolean
     */
    public static boolean isPppoeFlow(FlowRule flowRule) {
        EthTypeCriterion ethTypeCriterion = (EthTypeCriterion) flowRule.selector()
                .getCriterion(Criterion.Type.ETH_TYPE);

        if (ethTypeCriterion == null) {
            return false;
        }
        return EthType.EtherType.PPPoED.ethType().equals(ethTypeCriterion.ethType());
    }

    /**
     * Return true if the flow is a Data flow.
     * @param flowRule The FlowRule to evaluate
     * @return boolean
     */
    public static boolean isDataFlow(FlowRule flowRule) {
        // we consider subscriber flows the one that matches on VLAN_VID
        // method is valid only because it's the last check after EAPOL and DHCP.
        // this matches mcast flows as well, if we want to avoid that we can
        // filter out the elements that have groups in the treatment or
        // mcastIp in the selector
        // IPV4_DST:224.0.0.22/32
        // treatment=[immediate=[GROUP:0x1]]

        return flowRule.selector().getCriterion(Criterion.Type.VLAN_VID) != null;
    }

    /**
     * Extracts and returns inPort selector from the FlowRule.
     *
     * @param flowRule The FlowRule to evaluate
     * @return PortNumber
     */
    public static PortNumber getPortNumberFromFlowRule(FlowRule flowRule) {
        PortCriterion inPort = (PortCriterion) flowRule.selector().getCriterion(Criterion.Type.IN_PORT);
        if (inPort != null) {
            return inPort.port();
        }
        return null;
    }

    /**
     * Constructs and returns the metadata from innerVlan, techProfileId and egressPort.
     *
     * @param innerVlan         inner vlan tag
     * @param techProfileId     technology profile
     * @param egressPort        outport
     * @return Metadata
     */
    public static Long createMetadata(VlanId innerVlan, int techProfileId, PortNumber egressPort) {
        if (techProfileId == NONE_TP_ID) {
            techProfileId = DEFAULT_TP_ID_DEFAULT;
        }

        Long writeMetadata = (long) techProfileId << 32 | egressPort.toLong();

        if (innerVlan != null && !VlanId.NONE.equals(innerVlan)) {
            writeMetadata |= (long) (innerVlan.id()) << 48;
        }

        return writeMetadata;
    }

    /***
     * Checks if the FlowRule is default eapol.
     * @param flowRule FlowRule to check.
     * @return true if FlowRule is default eapol.
     */
    public static boolean isDefaultEapolFlow(FlowRule flowRule) {
        EthTypeCriterion c = (EthTypeCriterion) flowRule.selector().getCriterion(Criterion.Type.ETH_TYPE);
        if (c == null) {
            return false;
        }
        if (c.ethType().equals(EthType.EtherType.EAPOL.ethType())) {
            AtomicBoolean isDefault = new AtomicBoolean(false);
            flowRule.treatment().allInstructions().forEach(instruction -> {
                if (instruction.type() == L2MODIFICATION) {
                    L2ModificationInstruction modificationInstruction = (L2ModificationInstruction) instruction;
                    if (modificationInstruction.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
                        L2ModificationInstruction.ModVlanIdInstruction vlanInstruction =
                                (L2ModificationInstruction.ModVlanIdInstruction) modificationInstruction;
                        if (vlanInstruction.vlanId().id().equals(EAPOL_DEFAULT_VLAN)) {
                            isDefault.set(true);
                            return;
                        }
                    }
                }
            });
            return isDefault.get();
        }
        return false;
    }

    /***
     * Checks if the FlowRule is Subscriber eapol.
     * @param flowRule Flow Rule
     * @return true if FlowRule is Subscriber eapol.
     */
    public static boolean isSubscriberEapolFlow(FlowRule flowRule) {
        EthTypeCriterion c = (EthTypeCriterion) flowRule.selector().getCriterion(Criterion.Type.ETH_TYPE);
        if (c == null) {
            return false;
        }
        if (c.ethType().equals(EthType.EtherType.EAPOL.ethType())) {
            AtomicBoolean isSubscriber = new AtomicBoolean(false);
            flowRule.treatment().allInstructions().forEach(instruction -> {
                if (instruction.type() == L2MODIFICATION) {
                    L2ModificationInstruction modificationInstruction = (L2ModificationInstruction) instruction;
                    if (modificationInstruction.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
                        L2ModificationInstruction.ModVlanIdInstruction vlanInstruction =
                                (L2ModificationInstruction.ModVlanIdInstruction) modificationInstruction;
                        if (!vlanInstruction.vlanId().id().equals(EAPOL_DEFAULT_VLAN)) {
                            isSubscriber.set(true);
                            return;
                        }
                    }
                }
            });
            return isSubscriber.get();
        }
        return false;
    }
}
