/*
 * Copyright 2015 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.Device.DeviceType;
import org.onosproject.grpc.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.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);
        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.Device.MastershipRole translate(MastershipRole newRole) {
        switch (newRole) {
        case MASTER:
            return org.onosproject.grpc.Device.MastershipRole.MASTER;
        case STANDBY:
            return org.onosproject.grpc.Device.MastershipRole.STANDBY;
        case NONE:
        default:
            return org.onosproject.grpc.Device.MastershipRole.NONE;
        }
    }


    /**
     * Translates gRPC DeviceDescription to {@link DeviceDescription}.
     *
     * @param deviceDescription gRPC message
     * @return {@link DeviceDescription}
     */
    public static DeviceDescription translate(org.onosproject.grpc.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.Device.DeviceDescription translate(DeviceDescription deviceDescription) {

        return org.onosproject.grpc.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.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.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.Port.PortDescription translate(PortDescription portDescription) {
        // TODO How to deal with more specific Port...
        return org.onosproject.grpc.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.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.Port.PortStatistics translate(PortStatistics portStatistics) {
        // TODO implement adding missing fields
        return org.onosproject.grpc.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() {}
}
