/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * 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.incubator.rpc.grpc;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import org.onlab.packet.ChassisId;
import org.onosproject.grpc.net.Device.DeviceType;
import org.onosproject.grpc.net.Port.PortType;
import org.onosproject.net.Annotations;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.Port.Type;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.api.client.repackaged.com.google.common.annotations.Beta;

/**
 * gRPC message conversion related utilities.
 */
@Beta
public final class GrpcDeviceUtils {

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

    /**
     * Translates gRPC enum MastershipRole to ONOS enum.
     *
     * @param role mastership role in gRPC enum
     * @return equivalent in ONOS enum
     */
    public static MastershipRole translate(org.onosproject.grpc.net.Device.MastershipRole role) {
        switch (role) {
        case NONE:
            return MastershipRole.NONE;
        case MASTER:
            return MastershipRole.MASTER;
        case STANDBY:
            return MastershipRole.STANDBY;
        case UNRECOGNIZED:
            log.warn("Unrecognized MastershipRole gRPC message: {}", role);
            return MastershipRole.NONE;
        default:
            return MastershipRole.NONE;
        }
    }

    /**
     * Translates ONOS enum MastershipRole to gRPC enum.
     *
     * @param newRole ONOS' mastership role
     * @return equivalent in gRPC message enum
     */
    public static org.onosproject.grpc.net.Device.MastershipRole translate(MastershipRole newRole) {
        switch (newRole) {
        case MASTER:
            return org.onosproject.grpc.net.Device.MastershipRole.MASTER;
        case STANDBY:
            return org.onosproject.grpc.net.Device.MastershipRole.STANDBY;
        case NONE:
        default:
            return org.onosproject.grpc.net.Device.MastershipRole.NONE;
        }
    }


    /**
     * Translates gRPC DeviceDescription to {@link DeviceDescription}.
     *
     * @param deviceDescription gRPC message
     * @return {@link DeviceDescription}
     */
    public static DeviceDescription translate(org.onosproject.grpc.net.Device.DeviceDescription deviceDescription) {
        URI uri = URI.create(deviceDescription.getDeviceUri());
        Device.Type type = translate(deviceDescription.getType());
        String manufacturer = deviceDescription.getManufacturer();
        String hwVersion = deviceDescription.getHwVersion();
        String swVersion = deviceDescription.getSwVersion();
        String serialNumber = deviceDescription.getSerialNumber();
        ChassisId chassis = new ChassisId(deviceDescription.getChassisId());
        return new DefaultDeviceDescription(uri, type, manufacturer,
                                            hwVersion, swVersion, serialNumber,
                                            chassis,
                                            asAnnotations(deviceDescription.getAnnotations()));
    }

    /**
     * Translates {@link DeviceDescription} to gRPC DeviceDescription message.
     *
     * @param deviceDescription {@link DeviceDescription}
     * @return gRPC DeviceDescription message
     */
    public static org.onosproject.grpc.net.Device.DeviceDescription translate(DeviceDescription deviceDescription) {

        return org.onosproject.grpc.net.Device.DeviceDescription.newBuilder()
            .setDeviceUri(deviceDescription.deviceUri().toString())
            .setType(translate(deviceDescription.type()))
            .setManufacturer(deviceDescription.manufacturer())
            .setHwVersion(deviceDescription.hwVersion())
            .setSwVersion(deviceDescription.swVersion())
            .setSerialNumber(deviceDescription.serialNumber())
            .setChassisId(deviceDescription.chassisId().toString())
            .putAllAnnotations(asMap(deviceDescription.annotations()))
            .build();
    }


    /**
     * Translates gRPC DeviceType to {@link Device.Type}.
     *
     * @param type      gRPC message
     * @return  {@link Device.Type}
     */
    public static Device.Type translate(org.onosproject.grpc.net.Device.DeviceType type) {
        switch (type) {
        case BALANCER:
            return Device.Type.BALANCER;
        case CONTROLLER:
            return Device.Type.CONTROLLER;
        case FIBER_SWITCH:
            return Device.Type.FIBER_SWITCH;
        case FIREWALL:
            return Device.Type.FIREWALL;
        case IDS:
            return Device.Type.IDS;
        case IPS:
            return Device.Type.IPS;
        case MICROWAVE:
            return Device.Type.MICROWAVE;
        case OTHER:
            return Device.Type.OTHER;
        case OTN:
            return Device.Type.OTN;
        case ROADM:
            return Device.Type.ROADM;
        case ROADM_OTN:
            return Device.Type.ROADM_OTN;
        case ROUTER:
            return Device.Type.ROUTER;
        case SWITCH:
            return Device.Type.SWITCH;
        case VIRTUAL:
            return Device.Type.VIRTUAL;

        case UNRECOGNIZED:
        default:
            log.warn("Unexpected DeviceType: {}", type);
            return Device.Type.OTHER;
        }
    }

    /**
     * Translates {@link Type} to gRPC DeviceType.
     *
     * @param type {@link Type}
     * @return  gRPC message
     */
    public static DeviceType translate(Device.Type type) {
        switch (type) {
        case BALANCER:
            return DeviceType.BALANCER;
        case CONTROLLER:
            return DeviceType.CONTROLLER;
        case FIBER_SWITCH:
            return DeviceType.FIBER_SWITCH;
        case FIREWALL:
            return DeviceType.FIREWALL;
        case IDS:
            return DeviceType.IDS;
        case IPS:
            return DeviceType.IPS;
        case MICROWAVE:
            return DeviceType.MICROWAVE;
        case OTHER:
            return DeviceType.OTHER;
        case OTN:
            return DeviceType.OTN;
        case ROADM:
            return DeviceType.ROADM;
        case ROADM_OTN:
            return DeviceType.ROADM_OTN;
        case ROUTER:
            return DeviceType.ROUTER;
        case SWITCH:
            return DeviceType.SWITCH;
        case VIRTUAL:
            return DeviceType.VIRTUAL;

        default:
            log.warn("Unexpected Device.Type: {}", type);
            return DeviceType.OTHER;
        }
    }

    /**
     * Translates gRPC PortDescription message to {@link PortDescription}.
     *
     * @param portDescription gRPC message
     * @return {@link PortDescription}
     */
    public static PortDescription translate(org.onosproject.grpc.net.Port.PortDescription portDescription) {
        PortNumber number = PortNumber.fromString(portDescription.getPortNumber());
        boolean isEnabled = portDescription.getIsEnabled();
        Port.Type type = translate(portDescription.getType());
        long portSpeed = portDescription.getPortSpeed();
        SparseAnnotations annotations = asAnnotations(portDescription.getAnnotations());
        // TODO How to deal with more specific Port...
        return new DefaultPortDescription(number, isEnabled, type, portSpeed, annotations);
    }

    /**
     * Translates {@link PortDescription} to gRPC PortDescription message.
     *
     * @param portDescription {@link PortDescription}
     * @return gRPC PortDescription message
     */
    public static org.onosproject.grpc.net.Port.PortDescription translate(PortDescription portDescription) {
        // TODO How to deal with more specific Port...
        return org.onosproject.grpc.net.Port.PortDescription.newBuilder()
                .setPortNumber(portDescription.portNumber().toString())
                .setIsEnabled(portDescription.isEnabled())
                .setType(translate(portDescription.type()))
                .setPortSpeed(portDescription.portSpeed())
                .putAllAnnotations(asMap(portDescription.annotations()))
                .build();
    }

    /**
     * Translates gRPC PortType to {@link Port.Type}.
     *
     * @param type      gRPC message
     * @return  {@link Port.Type}
     */
    public static Port.Type translate(PortType type) {
        switch (type) {
        case COPPER:
            return Type.COPPER;
        case FIBER:
            return Type.FIBER;
        case OCH:
            return Type.OCH;
        case ODUCLT:
            return Type.ODUCLT;
        case OMS:
            return Type.OMS;
        case PACKET:
            return Type.PACKET;
        case VIRTUAL:
            return Type.VIRTUAL;

        case UNRECOGNIZED:
        default:
            log.warn("Unexpected PortType: {}", type);
            return Type.COPPER;
        }
    }

    /**
     * Translates {@link Port.Type} to gRPC PortType.
     *
     * @param type      {@link Port.Type}
     * @return  gRPC message
     */
    public static PortType translate(Port.Type type) {
        switch (type) {
        case COPPER:
            return PortType.COPPER;
        case FIBER:
            return PortType.FIBER;
        case OCH:
            return PortType.OCH;
        case ODUCLT:
            return PortType.ODUCLT;
        case OMS:
            return PortType.OMS;
        case PACKET:
            return PortType.PACKET;
        case VIRTUAL:
            return PortType.VIRTUAL;

        default:
            log.warn("Unexpected Port.Type: {}", type);
            return PortType.COPPER;
        }
    }

    /**
     * Translates gRPC PortStatistics message to {@link PortStatistics}.
     *
     * @param portStatistics gRPC PortStatistics message
     * @return {@link PortStatistics}
     */
    public static PortStatistics translate(org.onosproject.grpc.net.Port.PortStatistics portStatistics) {
        // TODO implement adding missing fields
        return DefaultPortStatistics.builder()
                .setPort(portStatistics.getPort())
                .setPacketsReceived(portStatistics.getPacketsReceived())
                .setPacketsSent(portStatistics.getPacketsSent())
                .build();
    }

    /**
     * Translates {@link PortStatistics} to gRPC PortStatistics message.
     *
     * @param portStatistics {@link PortStatistics}
     * @return gRPC PortStatistics message
     */
    public static org.onosproject.grpc.net.Port.PortStatistics translate(PortStatistics portStatistics) {
        // TODO implement adding missing fields
        return org.onosproject.grpc.net.Port.PortStatistics.newBuilder()
                .setPort(portStatistics.port())
                .setPacketsReceived(portStatistics.packetsReceived())
                .setPacketsSent(portStatistics.packetsSent())
                .build();
    }

    // may be this can be moved to Annotation itself or AnnotationsUtils
    /**
     * Converts Annotations to Map of Strings.
     *
     * @param annotations {@link Annotations}
     * @return Map of annotation key and values
     */
    public static Map<String, String> asMap(Annotations annotations) {
        if (annotations instanceof DefaultAnnotations) {
            return ((DefaultAnnotations) annotations).asMap();
        }
        Map<String, String> map = new HashMap<>();
        annotations.keys()
            .forEach(k -> map.put(k, annotations.value(k)));

        return map;
    }

    // may be this can be moved to Annotation itself or AnnotationsUtils
    /**
     * Converts Map of Strings to {@link SparseAnnotations}.
     *
     * @param annotations Map of annotation key and values
     * @return {@link SparseAnnotations}
     */
    public static SparseAnnotations asAnnotations(Map<String, String> annotations) {
        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
        annotations.entrySet().forEach(e -> {
                if (e.getValue() != null) {
                    builder.set(e.getKey(), e.getValue());
                } else {
                    builder.remove(e.getKey());
                }
            });
        return builder.build();
    }

    // Utility class not intended for instantiation.
    private GrpcDeviceUtils() {}
}
