/*
 * 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;

import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.opencord.sadis.BaseInformationService;
import org.opencord.sadis.SadisService;
import org.opencord.sadis.SubscriberAndDeviceInformation;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;

import java.util.List;
import java.util.Optional;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * The implementation of the OltDeviceService.
 */
@Component(immediate = true)
public class OltDeviceService implements OltDeviceServiceInterface {

    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
    private final Logger log = getLogger(getClass());

    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
            bind = "bindSadisService",
            unbind = "unbindSadisService",
            policy = ReferencePolicy.DYNAMIC)
    protected volatile SadisService sadisService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected MastershipService mastershipService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected LeadershipService leadershipService;

    @Activate
    public void activate() {
        log.info("Activated");
    }

    /**
     * Returns true if the device is an OLT.
     *
     * @param device the Device to be checked
     * @return boolean
     */
    public boolean isOlt(Device device) {
        return getOltInfo(device) != null;
    }

    private SubscriberAndDeviceInformation getOltInfo(Device dev) {
        if (subsService == null) {
            return null;
        }
        String devSerialNo = dev.serialNumber();
        return subsService.get(devSerialNo);
    }


    /**
     * Returns true if the port is an NNI Port on the OLT.
     * NOTE: We can check if a port is a NNI based on the SADIS config, specifically the uplinkPort section
     *
     * @param dev  the Device this port belongs to
     * @param portNumber the PortNumber to be checked
     * @return boolean
     */
    @Override
    public boolean isNniPort(Device dev, PortNumber portNumber) {
        SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
        return deviceInfo != null && portNumber.toLong() == deviceInfo.uplinkPort();
    }

    @Override
    public Optional<Port> getNniPort(Device device) {
        SubscriberAndDeviceInformation deviceInfo = getOltInfo(device);
        if (deviceInfo == null) {
            return Optional.empty();
        }
        List<Port> ports = deviceService.getPorts(device.id());
        if (log.isTraceEnabled()) {
            log.trace("Get NNI Port looks for NNI in: {}", ports);
        }
        return ports.stream()
                .filter(p -> p.number().toLong() == deviceInfo.uplinkPort())
                .findFirst();
    }

    protected void bindSadisService(SadisService service) {
        this.subsService = service.getSubscriberInfoService();
        log.info("Sadis service is loaded");
    }

    protected void unbindSadisService(SadisService service) {
        this.subsService = null;
        log.info("Sadis service is unloaded");
    }

    /**
     * Checks for mastership or falls back to leadership on deviceId.
     * If the device is available use mastership,
     * otherwise fallback on leadership.
     * Leadership on the device topic is needed because the master can be NONE
     * in case the device went away, we still need to handle events
     * consistently
     *
     * @param deviceId The device ID to check.
     * @return boolean (true if the current instance is managing the device)
     */
    @Override
    public boolean isLocalLeader(DeviceId deviceId) {
        if (deviceService.isAvailable(deviceId)) {
            return mastershipService.isLocalMaster(deviceId);
        } else {
            // Fallback with Leadership service - device id is used as topic
            NodeId leader = leadershipService.runForLeadership(
                    deviceId.toString()).leaderNodeId();
            // Verify if this node is the leader
            return clusterService.getLocalNode().id().equals(leader);
        }
    }
}
