/*
 * Copyright 2021-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.opencord.olt.impl.fttb;

import org.onlab.packet.MacAddress;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.Port;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.host.HostService;
import org.opencord.sadis.SubscriberAndDeviceInformation;
import org.opencord.sadis.UniTagInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Optional;

/**
 * Utility class for holding FTTB constants and utility methods.
 */
public final class FttbUtils {

    public static final String FTTB_FLOW_DIRECTION = "fttbFlowDirection";
    public static final String FTTB_FLOW_UPSTREAM = "fttbFlowUpstream";
    public static final String FTTB_FLOW_DOWNSTREAM = "fttbFlowDownstream";

    public static final String FTTB_SERVICE_NAME = "fttbServiceName";
    public static final String FTTB_SERVICE_DPU_MGMT_TRAFFIC = "DPU_MGMT_TRAFFIC";
    public static final String FTTB_SERVICE_DPU_ANCP_TRAFFIC = "DPU_ANCP_TRAFFIC";
    public static final String FTTB_SERVICE_SUBSCRIBER_TRAFFIC = "FTTB_SUBSCRIBER_TRAFFIC";

    private static final Logger log = LoggerFactory.getLogger(FttbUtils.class);

    private FttbUtils() {
    }

    /**
     * Checks if the FlowObjective qualifies as FTTB rule.
     *
     * @param fwd ForwardingObjective rule.
     * @return true if the fwd is FTTB rule.
     */
    public static boolean isFttbRule(ForwardingObjective fwd) {
        String serviceName = fwd.annotations().value(FTTB_SERVICE_NAME);

        if (serviceName == null) {
            if (log.isTraceEnabled()) {
                log.trace("Service name not found for : {} ", fwd);
            }
            return false;
        }

        return isFttbService(serviceName);
    }

    /**
     * Checks if the UniTagInformation is a FTTB subscriber.
     *
     * @param uti The UniTagInformation to check for.
     * @return true if the uti is FTTB subscriber.
     */
    public static boolean isFttbService(UniTagInformation uti) {
        String serviceName = uti.getServiceName();

        if (serviceName == null) {
            log.warn("Could not find service name for {}", uti);
            return false;
        }

        return isFttbService(serviceName);
    }

    /**
     * Checks if the UniTagInformation is FTTB DPU or ANCP service.
     *
     * @param uti The UniTagInformation to check for.
     * @return true if the uti is FTTB DPU or ANCP service.
     */
    public static boolean isFttbDpuOrAncpService(UniTagInformation uti) {
        String serviceName = uti.getServiceName();

        if (serviceName == null) {
            log.trace("Could not find service name for {}", uti);
            return false;
        }

        switch (serviceName) {
            case FTTB_SERVICE_DPU_MGMT_TRAFFIC:
            case FTTB_SERVICE_DPU_ANCP_TRAFFIC:
                return true;
            default:
                return false;
        }
    }

    /**
     * Adds match conditions to FilteringObjective.Builder for FTTB.
     * @param dhcpBuilder FilteringObjective.Builder
     * @param uti UniTagInformation
     */
    public static void addUpstreamDhcpCondition(FilteringObjective.Builder dhcpBuilder,
                                                UniTagInformation uti) {
        dhcpBuilder.addCondition(Criteria.matchVlanId(uti.getPonCTag()));
        if (uti.getUsPonCTagPriority() != -1) {
            dhcpBuilder.addCondition(Criteria.matchVlanPcp((byte) uti.getUsPonCTagPriority()));
        }
    }

    /**
     * Adds Instructions to TrafficTreatment.Builder for FTTB.
     * @param treatmentBuilder TrafficTreatment.Builder
     * @param uti UniTagInformation
     */
    public static void addUpstreamDhcpTreatment(TrafficTreatment.Builder treatmentBuilder, UniTagInformation uti) {
        treatmentBuilder.setVlanId(uti.getPonSTag());

        if (uti.getUsPonSTagPriority() != -1) {
            treatmentBuilder.setVlanPcp((byte) uti.getUsPonSTagPriority());
        }
    }

    private static boolean isFttbService(String serviceName) {
        if (serviceName == null) {
            return false;
        }

        switch (serviceName) {
            case FTTB_SERVICE_DPU_MGMT_TRAFFIC:
            case FTTB_SERVICE_DPU_ANCP_TRAFFIC:
            case FTTB_SERVICE_SUBSCRIBER_TRAFFIC:
                return true;
            default:
                if (log.isTraceEnabled()) {
                    log.trace("Service name {} is not one for FTTB", serviceName);
                }
                return false;
        }
    }

    /**
     * Returns mac address from the Dhcp Enabled UniTagInformation for a FTTB service.
     *
     * @param hostService    Service for interacting with the inventory of end-station hosts
     * @param si             Information about a subscriber
     * @param deviceId       Device id for mac lookup.
     * @param port           Uni port on the device for mac lookup.
     * @param localAddresses Map of the addresses that this app has locally
     * @return Mac address of the subscriber.
     */
    public static MacAddress getMacAddressFromDhcpEnabledUti(HostService hostService,
                                                             SubscriberAndDeviceInformation si,
                                                             DeviceId deviceId,
                                                             Port port,
                                                             Map<ConnectPoint, MacAddress> localAddresses) {
        for (UniTagInformation uniTagInfo : si.uniTagList()) {
            boolean isMacLearningEnabled = uniTagInfo.getEnableMacLearning();
            if (isMacLearningEnabled) {
                ConnectPoint cp = new ConnectPoint(deviceId, port.number());
                Optional<Host> optHost = hostService.getConnectedHosts(cp)
                        .stream().filter(host -> host.vlan().equals(uniTagInfo.getPonSTag())).findFirst();
                if (optHost.isPresent()) {
                    MacAddress learntMac = optHost.get().mac();
                    if (learntMac != null) {
                        localAddresses.put(cp, learntMac);
                        log.info("Stored mac {} locally for connectPoint {}", learntMac, cp);
                        return learntMac;
                    }
                } else {
                    MacAddress localMac = localAddresses.get(new ConnectPoint(deviceId, port.number()));
                    if (localMac != null) {
                        log.debug("Returning local mac {} for connectPoint {}", localMac, cp);
                        return localMac;
                    }
                }
            } else if (uniTagInfo.getConfiguredMacAddress() != null &&
                    !uniTagInfo.getConfiguredMacAddress().isEmpty()) {
                log.info("Using configured mac address for FTTB {}", uniTagInfo.getConfiguredMacAddress());
                return MacAddress.valueOf(uniTagInfo.getConfiguredMacAddress());
            }
        }
        return null;
    }
}
