/*
 * 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.incubator.protobuf.models.net.device;

import org.onosproject.grpc.net.device.models.PortDescriptionProtoOuterClass.PortDescriptionProto;
import org.onosproject.grpc.net.device.models.PortEnumsProto;
import org.onosproject.grpc.net.device.models.PortStatisticsProtoOuterClass;
import org.onosproject.grpc.net.device.models.PortStatisticsProtoOuterClass.PortStatisticsProto;
import org.onosproject.incubator.protobuf.models.net.AnnotationsTranslator;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * gRPC message conversion related utilities for port service.
 */
public final class PortProtoTranslator {

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

    /**
     * Translates gRPC PortDescription message to {@link PortDescription}.
     *
     * @param portDescription gRPC message
     * @return {@link PortDescription}
     */
    public static PortDescription translate(PortDescriptionProto portDescription) {
        PortNumber number = PortNumber.fromString(portDescription.getPortNumber());
        boolean isEnabled = portDescription.getIsEnabled();
        Port.Type type = translate(portDescription.getType());
        long portSpeed = portDescription.getPortSpeed();
        SparseAnnotations annotations = AnnotationsTranslator.asAnnotations(portDescription.getAnnotationsMap());
        // 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 PortDescriptionProto translate(PortDescription portDescription) {
        return PortDescriptionProto.newBuilder()
                .setPortNumber(portDescription.portNumber().toString())
                .setIsEnabled(portDescription.isEnabled())
                .setType(translate(portDescription.type()))
                .setPortSpeed(portDescription.portSpeed())
                .putAllAnnotations(AnnotationsTranslator.asMap(portDescription.annotations()))
                .build();
    }

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

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

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

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

    /**
     * Translates gRPC PortStatistics message to {@link PortStatisticsProtoOuterClass}.
     *
     * @param portStatistics gRPC PortStatistics message
     * @return {@link PortStatisticsProtoOuterClass}
     */
    public static PortStatistics translate(PortStatisticsProto 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 PortStatisticsProto translate(PortStatistics portStatistics) {
        // TODO implement adding missing fields
        return PortStatisticsProto.newBuilder()
                .setPort(portStatistics.port())
                .setPacketsReceived(portStatistics.packetsReceived())
                .setPacketsSent(portStatistics.packetsSent())
                .build();
    }

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