/*
 * 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.net.optical.util;

import org.onosproject.net.optical.OduCltPort;

import org.onosproject.core.ApplicationId;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.Path;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.OpticalCircuitIntent;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.intent.OpticalOduIntent;
import org.onosproject.net.optical.OchPort;

import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;

import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Utility class for optical intents.
 */
public final class OpticalIntentUtility {

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

    private OpticalIntentUtility() {
    }

    /**
     * Returns a new optical intent created from the method parameters.
     *
     * @param ingress ingress description (device/port)
     * @param egress egress description (device/port)
     * @param deviceService device service
     * @param key intent key
     * @param appId application id
     * @param bidirectional if this argument is true, the optical link created
     * will be bidirectional, otherwise the link will be unidirectional.
     * @param signal optical signal
     *
     * @return created intent
     */
    public static Intent createOpticalIntent(ConnectPoint ingress, ConnectPoint
            egress, DeviceService deviceService, Key key, ApplicationId appId, boolean
            bidirectional, OchSignal signal) {

        Intent intent = null;

        if (ingress == null || egress == null) {
            log.debug("Invalid endpoint(s); could not create optical intent");
            return intent;
        }

        DeviceService ds = opticalView(deviceService);

        Port srcPort = ds.getPort(ingress.deviceId(), ingress.port());
        Port dstPort = ds.getPort(egress.deviceId(), egress.port());

        if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) {
            Device srcDevice = ds.getDevice(ingress.deviceId());
            Device dstDevice = ds.getDevice(egress.deviceId());

            // continue only if both OduClt port's Devices are of the same type
            if (!(srcDevice.type().equals(dstDevice.type()))) {
                log.debug("Devices without same deviceType: SRC {} and DST={}", srcDevice.type(), dstDevice.type());
                return intent;
            }

            CltSignalType signalType = ((OduCltPort) srcPort).signalType();
            if (Device.Type.ROADM.equals(srcDevice.type()) ||
                    Device.Type.ROADM_OTN.equals(srcDevice.type()) ||
                    Device.Type.OLS.equals(srcDevice.type())) {
                intent = OpticalCircuitIntent.builder()
                        .appId(appId)
                        .key(key)
                        .src(ingress)
                        .dst(egress)
                        .signalType(signalType)
                        .bidirectional(bidirectional)
                        .build();
            } else if (Device.Type.OTN.equals(srcDevice.type())) {
                intent = OpticalOduIntent.builder()
                        .appId(appId)
                        .key(key)
                        .src(ingress)
                        .dst(egress)
                        .signalType(signalType)
                        .bidirectional(bidirectional)
                        .build();
            } else {
                log.debug("Wrong Device Type for connect points {} and {}", ingress, egress);
            }
        } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) {
            OduSignalType signalType = ((OchPort) srcPort).signalType();
            intent = OpticalConnectivityIntent.builder()
                    .appId(appId)
                    .key(key)
                    .src(ingress)
                    .dst(egress)
                    .signalType(signalType)
                    .bidirectional(bidirectional)
                    .ochSignal(signal)
                    .build();
        } else {
            log.debug("Unable to create optical intent between connect points {} and {}", ingress, egress);
        }

        return intent;
    }

    /**
     * Returns a new optical intent created from the method parameters, strict suggestedPath is specified.
     *
     * @param ingress ingress description (device/port)
     * @param egress egress description (device/port)
     * @param deviceService device service
     * @param key intent key
     * @param appId application id
     * @param bidirectional if this argument is true, the optical link created
     * will be bidirectional, otherwise the link will be unidirectional.
     * @param signal optical signal
     * @param path suggested path for the intent
     *
     * @return created intent
     */
    public static Intent createExplicitOpticalIntent(ConnectPoint ingress, ConnectPoint
            egress, DeviceService deviceService, Key key, ApplicationId appId, boolean
                                                     bidirectional, OchSignal signal, Path path) {

        Intent intent = null;

        if (ingress == null || egress == null) {
            log.error("Invalid endpoint(s); could not create optical intent");
            return intent;
        }

        DeviceService ds = opticalView(deviceService);

        Port srcPort = ds.getPort(ingress.deviceId(), ingress.port());
        Port dstPort = ds.getPort(egress.deviceId(), egress.port());

        if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) {
            Device srcDevice = ds.getDevice(ingress.deviceId());
            Device dstDevice = ds.getDevice(egress.deviceId());

            // continue only if both OduClt port's Devices are of the same type
            if (!(srcDevice.type().equals(dstDevice.type()))) {
                log.debug("Devices without same deviceType: SRC={} and DST={}", srcDevice.type(), dstDevice.type());
                return intent;
            }

            CltSignalType signalType = ((OduCltPort) srcPort).signalType();
            if (Device.Type.ROADM.equals(srcDevice.type()) ||
                    Device.Type.ROADM_OTN.equals(srcDevice.type()) ||
                    Device.Type.OLS.equals(srcDevice.type())) {
                intent = OpticalCircuitIntent.builder()
                        .appId(appId)
                        .key(key)
                        .src(ingress)
                        .dst(egress)
                        .signalType(signalType)
                        .bidirectional(bidirectional)
                        .build();
            } else if (Device.Type.OTN.equals(srcDevice.type())) {
                intent = OpticalOduIntent.builder()
                        .appId(appId)
                        .key(key)
                        .src(ingress)
                        .dst(egress)
                        .signalType(signalType)
                        .bidirectional(bidirectional)
                        .build();
            } else {
                log.error("Wrong Device Type for connect points: " +
                        "ingress {} of type {}; egress {} of type {}",
                        ingress, srcDevice.type(), egress, dstDevice.type());
            }
        } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) {
            OduSignalType signalType = ((OchPort) srcPort).signalType();
            intent = OpticalConnectivityIntent.builder()
                    .appId(appId)
                    .key(key)
                    .src(ingress)
                    .dst(egress)
                    .signalType(signalType)
                    .bidirectional(bidirectional)
                    .ochSignal(signal)
                    .suggestedPath(path)
                    .build();
        } else {
            log.error("Unable to create explicit optical intent between connect points {} and {}", ingress, egress);
        }

        return intent;
    }
}
