/*
 * 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.net.device.impl;

import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.basics.OpticalPortConfig;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.PortDescription;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;

import static org.junit.Assert.assertEquals;
import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;

public class OpticalPortOperatorTest {
    private static final DeviceId DID = DeviceId.deviceId("op-test");
    private static final long PORT_NUMBER = 100;
    private static final String CFG_KEY = "optical";

    private static final String CFG_PORT_NAME = "cfg-name";
    private static final long CFG_STATIC_LAMBDA = 300L;

    private static final String DESC_PORT_NAME = "test-port-100";
    private static final PortNumber NAMED = PortNumber.portNumber(PORT_NUMBER, DESC_PORT_NAME);
    private static final PortNumber UNNAMED = PortNumber.portNumber(PORT_NUMBER);

    private static final String DESC_STATIC_PORT = "out-port-200";
    private static final SparseAnnotations SA = DefaultAnnotations.builder()
                                                    .set(AnnotationKeys.STATIC_PORT, DESC_STATIC_PORT)
                                                    .build();

    private static final PortDescription N_DESC = oduCltPortDescription(
            NAMED, true, CltSignalType.CLT_100GBE, SA);
    private static final PortDescription U_DESC = oduCltPortDescription(
            UNNAMED, true, CltSignalType.CLT_100GBE, SA);

    private final ConfigApplyDelegate delegate = new MockCfgDelegate();
    private final ObjectMapper mapper = new ObjectMapper();

    private static final ConnectPoint CP = new ConnectPoint(DID, UNNAMED);

    private static final OpticalPortConfig OPC = new OpticalPortConfig();

    @Before
    public void setUp() {
        OPC.init(CP, CFG_KEY, JsonNodeFactory.instance.objectNode(), mapper, delegate);
    }

    @Test
    public void testConfigPortName() {
        OPC.portType(Port.Type.ODUCLT)
            .portNumberName(PORT_NUMBER)
            .portName(CFG_PORT_NAME);

        PortDescription res;
        // full desc + opc with name
        res = OpticalPortOperator.combine(OPC, N_DESC);
        assertEquals("Configured port name expected",
                     CFG_PORT_NAME, res.portNumber().name());
        assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));

        res = OpticalPortOperator.combine(OPC, U_DESC);
        assertEquals("Configured port name expected",
                     CFG_PORT_NAME, res.portNumber().name());
        assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
    }

    @Test
    public void testConfigAddStaticLambda() {
        OPC.portType(Port.Type.ODUCLT)
            .portNumberName(PORT_NUMBER)
            .staticLambda(CFG_STATIC_LAMBDA);

        PortDescription res;
        res = OpticalPortOperator.combine(OPC, N_DESC);
        assertEquals("Original port name expected",
                     DESC_PORT_NAME, res.portNumber().name());
        assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
        long sl = Long.valueOf(res.annotations().value(AnnotationKeys.STATIC_LAMBDA));
        assertEquals(CFG_STATIC_LAMBDA, sl);
    }

    @Test
    public void testEmptyConfig() {
        OPC.portType(Port.Type.ODUCLT)
            .portNumberName(PORT_NUMBER);

        PortDescription res;
        res = OpticalPortOperator.combine(OPC, N_DESC);
        assertEquals("Configured port name expected",
                     DESC_PORT_NAME, res.portNumber().name());
        assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
    }


    private class MockCfgDelegate implements ConfigApplyDelegate {

        @Override
        public void onApply(@SuppressWarnings("rawtypes") Config config) {
            config.apply();
        }

    }
}
