/*
 * Copyright 2018-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.onosproject.onlpdemo;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import gnmi.Gnmi;
import org.onlab.util.SharedExecutors;
import org.onosproject.gnmi.api.GnmiClient;
import org.onosproject.gnmi.api.GnmiController;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.ui.UiExtension;
import org.onosproject.ui.UiExtensionService;
import org.onosproject.ui.UiMessageHandlerFactory;
import org.onosproject.ui.UiTopoOverlay;
import org.onosproject.ui.UiTopoOverlayFactory;
import org.onosproject.ui.UiView;
import org.onosproject.ui.UiViewHidden;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;

/**
 * Extends the ONOS GUI to display various ONLP device data.
 */
@Component(immediate = true, service = OnlpDemoManager.class)
public class OnlpDemoManager {

    private Logger log = LoggerFactory.getLogger(getClass());

    private static final String EXTENSION_ID = "onlpdemo";
    private static final String OVERLAY_ID = "od-overlay";

    private static final String OVERLAY_VIEW_ID = "odTopov";
    private static final String TABLE_VIEW_ID = "onlp";

    // List of application views
    private final List<UiView> uiViews = ImmutableList.of(
            new UiViewHidden(OVERLAY_VIEW_ID),
            new UiViewHidden(TABLE_VIEW_ID)
    );

    // Factory for UI message handlers
    private final UiMessageHandlerFactory messageHandlerFactory =
            () -> ImmutableList.of(new OnlpDemoViewMessageHandler(new GnmiOnlpDataSource()));

    // Factory for UI topology overlays
    private final UiTopoOverlayFactory topoOverlayFactory =
            () -> ImmutableList.of(new UiTopoOverlay(OVERLAY_ID));

    // Application UI extension
    protected UiExtension extension =
            new UiExtension.Builder(getClass().getClassLoader(), uiViews)
                    .resourcePath(EXTENSION_ID)
                    .messageHandlerFactory(messageHandlerFactory)
                    .topoOverlayFactory(topoOverlayFactory)
                    .build();

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected NetworkConfigService networkConfigService;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected UiExtensionService uiExtensionService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected GnmiController gnmiController;

    @Activate
    protected void activate() {
        uiExtensionService.register(extension);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        uiExtensionService.unregister(extension);
        log.info("Stopped");
    }


    public class OnlpData {
        String id;
        String presence;
        String vendor;
        String modelNumber;
        String serialNumber;
        String formFactor;

        OnlpData(String id, String presence, String vendor, String modelNumber,
                 String serialNumber, String formFactor) {
            this.id = id;
            this.presence = presence;
            this.vendor = vendor;
            this.modelNumber = modelNumber;
            this.serialNumber = serialNumber;
            this.formFactor = formFactor;
        }
    }

    public interface OnlpDataSource {
        List<OnlpData> getData(DeviceId deviceId);
    }


    public class GnmiOnlpDataSource implements OnlpDataSource {

        private Map<DeviceId, List<OnlpData>> cache = Maps.newConcurrentMap();

        GnmiOnlpDataSource() {
            SharedExecutors.getTimer().schedule(new TimerTask() {
                @Override
                public void run() {
                    cache.keySet().forEach(GnmiOnlpDataSource.this::fetchData);
                }
            }, 5000, 5000);
        }

        @Override
        public List<OnlpData> getData(DeviceId deviceId) {
            return cache.computeIfAbsent(deviceId, k -> ImmutableList.of());
        }

        private void fetchData(DeviceId deviceId) {
            ImmutableList.Builder<OnlpData> builder = ImmutableList.builder();
            GnmiClient gnmiClient = gnmiController.getClient(deviceId);
            deviceService.getPorts(deviceId)
                    .forEach(port -> builder.add(getOnlpData(gnmiClient, port)));
            cache.put(deviceId, builder.build());
        }

        private OnlpData getOnlpData(GnmiClient gnmiClient, Port port) {
            CompletableFuture<Gnmi.GetResponse> prReq = gnmiClient.get(fieldRequest(port, "present"));
            CompletableFuture<Gnmi.GetResponse> veReq = gnmiClient.get(fieldRequest(port, "vendor"));
            CompletableFuture<Gnmi.GetResponse> snReq = gnmiClient.get(fieldRequest(port, "serial-no"));
            CompletableFuture<Gnmi.GetResponse> vpReq = gnmiClient.get(fieldRequest(port, "vendor-part"));
            CompletableFuture<Gnmi.GetResponse> ffReq = gnmiClient.get(fieldRequest(port, "form-factor"));

            return new OnlpData("sfp-" + port.number().name().replaceFirst("/[0-9]", ""),
                                value(prReq).equals("PRESENT") ? "*" : "",
                                value(veReq), value(vpReq), value(snReq), value(ffReq));
        }

        private String value(CompletableFuture<Gnmi.GetResponse> req) {
            Gnmi.GetResponse response = Futures.getUnchecked(req);
            return response.getNotificationList().isEmpty() ?
                    "" : response.getNotification(0).getUpdate(0).getVal().getStringVal().trim();
        }

        private Gnmi.GetRequest fieldRequest(Port port, String field) {
            Gnmi.Path path = Gnmi.Path.newBuilder()
                    .addElem(Gnmi.PathElem.newBuilder().setName("components").build())
                    .addElem(Gnmi.PathElem.newBuilder().setName("component").putKey("name",
                                                                                    port.number().name()).build())
                    .addElem(Gnmi.PathElem.newBuilder().setName("transceiver").build())
                    .addElem(Gnmi.PathElem.newBuilder().setName("state").build())
                    .addElem(Gnmi.PathElem.newBuilder().setName(field).build())
                    .build();
            return Gnmi.GetRequest.newBuilder()
                    .addPath(path)
                    .setType(Gnmi.GetRequest.DataType.ALL)
                    .setEncoding(Gnmi.Encoding.PROTO)
                    .build();
        }
    }

}