/*
 * Copyright 2016 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.net.optical.device;

import static org.slf4j.LoggerFactory.getLogger;

import java.io.IOException;
import java.util.Optional;

import org.onosproject.net.Annotations;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
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.PortDescription;
import org.onosproject.net.optical.OchPort;
import org.onosproject.net.optical.impl.DefaultOchPort;
import org.onosproject.net.optical.json.OchSignalCodec;
import org.slf4j.Logger;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.annotations.Beta;

/**
 * OCh port related helpers.
 */
@Beta
public final class OchPortHelper {

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

    private static final ObjectMapper MAPPER = new ObjectMapper();

    // Annotation keys
    private static final String SIGNAL_TYPE = "signalType";
    private static final String TUNABLE = "tunable";
    private static final String LAMBDA = "lambda";

    /**
     * Creates OCh port DefaultPortDescription based on the supplied information.
     *
     * @param number      port number
     * @param isEnabled   port enabled state
     * @param signalType  ODU signal type
     * @param isTunable   tunable wavelength capability
     * @param lambda      OCh signal
     * @return OCh port DefaultPortDescription with OCh annotations
     */
    public static PortDescription ochPortDescription(PortNumber number,
                                                     boolean isEnabled,
                                                     OduSignalType signalType,
                                                     boolean isTunable,
                                                     OchSignal lambda) {
        return ochPortDescription(number, isEnabled, signalType, isTunable, lambda, DefaultAnnotations.EMPTY);
    }

    /**
     * Creates OCh port DefaultPortDescription based on the supplied information.
     *
     * @param number      port number
     * @param isEnabled   port enabled state
     * @param signalType  ODU signal type
     * @param isTunable   tunable wavelength capability
     * @param lambda      OCh signal
     * @param annotationsIn key/value annotations map
     * @return OCh port DefaultPortDescription with OCh annotations
     */
    public static PortDescription ochPortDescription(PortNumber number,
                                                     boolean isEnabled,
                                                     OduSignalType signalType,
                                                     boolean isTunable,
                                                     OchSignal lambda,
                                                     SparseAnnotations annotationsIn) {

        Builder builder = DefaultAnnotations.builder();
        builder.putAll(annotationsIn);

        builder.set(TUNABLE, String.valueOf(isTunable));
        builder.set(LAMBDA, OchSignalCodec.encode(lambda).toString());
        builder.set(SIGNAL_TYPE, signalType.toString());

        DefaultAnnotations annotations = builder.build();
        long portSpeed = 0; // FIXME assign appropriate value
        return new DefaultPortDescription(number, isEnabled, Port.Type.OCH, portSpeed, annotations);
    }

    /**
     * Creates OCh port DefaultPortDescription based on the supplied information.
     *
     * @param base        PortDescription to get basic information from
     * @param signalType  ODU signal type
     * @param isTunable   tunable wavelength capability
     * @param lambda      OCh signal
     * @param annotations key/value annotations map
     * @return OCh port DefaultPortDescription with OCh annotations
     */
    public static PortDescription ochPortDescription(PortDescription base,
                                                     OduSignalType signalType,
                                                     boolean isTunable,
                                                     OchSignal lambda,
                                                     SparseAnnotations annotations) {
        return ochPortDescription(base.portNumber(), base.isEnabled(), signalType, isTunable, lambda, annotations);
    }


    public static Optional<OchPort> asOchPort(Port port) {
        if (port instanceof OchPort) {
            return Optional.of((OchPort) port);
        }

        try {
            Annotations an = port.annotations();

            OduSignalType signalType = Enum.valueOf(OduSignalType.class,
                                                    an.value(SIGNAL_TYPE));

            boolean isTunable = Boolean.valueOf(an.value(TUNABLE));

            ObjectNode obj = (ObjectNode) MAPPER.readTree(an.value(LAMBDA));
            OchSignal lambda = OchSignalCodec.decode(obj);

            // Note: OCh specific annotations is not filtered-out here.
            //       DefaultOchPort should filter them, if necessary.
            return Optional.of(new DefaultOchPort(port, signalType, isTunable, lambda));

            // TODO: it'll be better to verify each inputs properly
            // instead of catching all these Exceptions.
        } catch (IOException | NullPointerException
                | IllegalArgumentException | ClassCastException e) {

            log.warn("{} was not well-formed OCh port.", port, e);
            return Optional.empty();
        }
    }

    // not meant to be instantiated
    private OchPortHelper() {}
}
