/*
 * 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.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.
     * @return Mac address of the subscriber.
     */
    public static MacAddress getMacAddressFromDhcpEnabledUti(HostService hostService,
                                                             SubscriberAndDeviceInformation si,
                                                             DeviceId deviceId,
                                                             Port port) {
        for (UniTagInformation uniTagInfo : si.uniTagList()) {
            boolean isMacLearningEnabled = uniTagInfo.getEnableMacLearning();
            if (isMacLearningEnabled) {
                Optional<Host> optHost = hostService.getConnectedHosts(new ConnectPoint(deviceId, port.number()))
                        .stream().filter(host -> host.vlan().equals(uniTagInfo.getPonSTag())).findFirst();
                if (optHost.isPresent()) {
                    if (optHost.get().mac() != null) {
                        return optHost.get().mac();
                    }
                }
            } 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;
    }
}
