/*
 * Copyright 2017-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.drivers.gnmi;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import gnmi.Gnmi;
import gnmi.Gnmi.GetRequest;
import gnmi.Gnmi.GetResponse;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
import org.onosproject.net.device.PortDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import static gnmi.Gnmi.Path;
import static gnmi.Gnmi.PathElem;
import static gnmi.Gnmi.Update;

/**
 * Class that discovers the device description and ports of a device that
 * supports the gNMI protocol and Openconfig models.
 */
public class OpenConfigGnmiDeviceDescriptionDiscovery
        extends AbstractGnmiHandlerBehaviour
        implements DeviceDescriptionDiscovery {

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

    private static final String LAST_CHANGE = "last-change";

    @Override
    public DeviceDescription discoverDeviceDetails() {
        return null;
    }

    @Override
    public List<PortDescription> discoverPortDetails() {
        if (!setupBehaviour()) {
            return Collections.emptyList();
        }
        log.debug("Discovering port details on device {}", handler().data().deviceId());

        final GetResponse response = getFutureWithDeadline(
                client.get(buildPortStateRequest()),
                "getting port details", GetResponse.getDefaultInstance());

        final Map<String, DefaultPortDescription.Builder> ports = Maps.newHashMap();
        final Map<String, DefaultAnnotations.Builder> annotations = Maps.newHashMap();

        // Creates port descriptions with port name and port number
        response.getNotificationList()
                .forEach(notification -> {
                    long timestamp = notification.getTimestamp();
                    notification.getUpdateList().forEach(update -> {
                        // /interfaces/interface[name=ifName]/state/...
                        final String ifName = update.getPath().getElem(1)
                                .getKeyMap().get("name");
                        if (!ports.containsKey(ifName)) {
                            ports.put(ifName, DefaultPortDescription.builder());
                            annotations.put(ifName, DefaultAnnotations.builder());
                        }
                        final DefaultPortDescription.Builder builder = ports.get(ifName);
                        final DefaultAnnotations.Builder annotationsBuilder = annotations.get(ifName);
                        parseInterfaceInfo(update, ifName, builder, annotationsBuilder, timestamp);
                    });
                });

        final List<PortDescription> portDescriptionList = Lists.newArrayList();
        ports.forEach((key, value) -> {
            DefaultAnnotations annotation = annotations.get(key).build();
            portDescriptionList.add(value.annotations(annotation).build());
        });
        return portDescriptionList;
    }

    private GetRequest buildPortStateRequest() {
        Path path = Path.newBuilder()
                .addElem(PathElem.newBuilder().setName("interfaces").build())
                .addElem(PathElem.newBuilder().setName("interface").putKey("name", "...").build())
                .addElem(PathElem.newBuilder().setName("state").build())
                .build();
        return GetRequest.newBuilder()
                .addPath(path)
                .setType(GetRequest.DataType.ALL)
                .setEncoding(Gnmi.Encoding.PROTO)
                .build();
    }

    /**
     * Parses the interface information.
     *
     * @param update the update received
     */
    private void parseInterfaceInfo(Update update,
                                    String ifName,
                                    DefaultPortDescription.Builder builder,
                                    DefaultAnnotations.Builder annotationsBuilder,
                                    long timestamp) {


        final Path path = update.getPath();
        final List<PathElem> elems = path.getElemList();
        final Gnmi.TypedValue val = update.getVal();
        if (elems.size() == 4) {
            // /interfaces/interface/state/ifindex
            // /interfaces/interface/state/oper-status
            final String pathElemName = elems.get(3).getName();
            switch (pathElemName) {
                case "ifindex": // port number
                    builder.withPortNumber(PortNumber.portNumber(val.getUintVal(), ifName));
                    return;
                case "oper-status":
                    builder.isEnabled(parseOperStatus(val.getStringVal()));
                    annotationsBuilder.set(LAST_CHANGE, String.valueOf(timestamp));
                    return;
                default:
                    break;
            }
        } else if (elems.size() == 5) {
            // /interfaces/interface/ethernet/config/port-speed
            final String pathElemName = elems.get(4).getName();
            if (pathElemName.equals("port-speed")) {
                builder.portSpeed(parsePortSpeed(val.getStringVal()));
                return;
            }
        }
        log.debug("Unknown path when parsing interface info: {}", path);
    }

    private boolean parseOperStatus(String operStatus) {
        switch (operStatus) {
            case "UP":
                return true;
            case "DOWN":
            default:
                return false;
        }
    }

    private long parsePortSpeed(String speed) {
        log.debug("Speed from config {}", speed);
        switch (speed) {
            case "SPEED_10MB":
                return 10;
            case "SPEED_100MB":
                return 100;
            case "SPEED_1GB":
                return 1000;
            case "SPEED_10GB":
                return 10000;
            case "SPEED_25GB":
                return 25000;
            case "SPEED_40GB":
                return 40000;
            case "SPEED_50GB":
                return 50000;
            case "SPEED_100GB":
                return 100000;
            default:
                log.warn("Unrecognized port speed string '{}'", speed);
                return 1000;
        }
    }
}
