/*
 * Copyright 2016-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.optical.intent.impl.compiler;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.AbstractProjectableModel;
import org.onosproject.net.Annotations;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.OduSignalUtils;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.Path;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.TributarySlot;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.driver.DriverServiceAdapter;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.intent.AbstractIntentTest;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.OpticalOduIntent;
import org.onosproject.net.optical.OduCltPort;
import org.onosproject.net.optical.OtuPort;
import org.onosproject.net.optical.impl.DefaultOduCltPort;
import org.onosproject.net.optical.impl.DefaultOtuPort;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.resource.MockResourceService;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyServiceAdapter;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.easymock.EasyMock.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
import static org.onosproject.net.Device.Type.OTN;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.OPTICAL;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;

public class OpticalOduIntentCompilerTest extends AbstractIntentTest {

    private static final String DEV1 = "of:1";
    private static final String DEV2 = "of:2";
    private static final String DEV3 = "of:3";

    static final Key KEY1 = Key.of(5L, APP_ID);

    private static final String STATIC_TRUE = "true";
    private static final String PNAME = "p2";

    private CoreService coreService;
    private IntentExtensionService intentExtensionService;
    private OpticalOduIntentCompiler sut;

    private final ApplicationId appId = new TestApplicationId("test");
    private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
            "m", "h", "s", "n", new ChassisId(0L));
    private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
            "m", "h", "s", "n", new ChassisId(1L));
    private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
            "m", "h", "s", "n", new ChassisId(2L));

    private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
    private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();

    // OduClt ports with signalType=1GBE
    private static final OduCltPort D1P1 =
            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(1), true, annotations1),
                                  CltSignalType.CLT_1GBE);
    private static final OduCltPort D3P2 =
            new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(2), true, annotations1),
                                  CltSignalType.CLT_1GBE);

    // Otu ports with signalType=ODU2
    private static final OtuPort D1P2 =
            new DefaultOtuPort(new DefaultPort(device1, PortNumber.portNumber(2), true, annotations2),
                               OtuSignalType.OTU2);
    private static final OtuPort D2P1 =
            new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(1), true, annotations2),
                               OtuSignalType.OTU2);
    private static final OtuPort D2P2 =
            new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(2), true, annotations2),
                               OtuSignalType.OTU2);
    private static final OtuPort D3P1 =
            new DefaultOtuPort(new DefaultPort(device3, PortNumber.portNumber(1), true, annotations2),
                               OtuSignalType.OTU2);

    // OduClt ports with signalType=10GBE
    private static final OduCltPort D1P3 =
            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(3), true, annotations1),
                                  CltSignalType.CLT_10GBE);
    private static final OduCltPort D3P3 =
            new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(3), true, annotations1),
                                  CltSignalType.CLT_10GBE);

    // OduCltPort ConnectPoints
    private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
    private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
    private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
    private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());

    // OtuPort ConnectPoints
    private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
    private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
    private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
    private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());

    private final List<Link> links = Arrays.asList(
            DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
            DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
    );
    private final Path path = new DefaultPath(PID, links, 3);

    private OpticalOduIntent intent;

    /**
     * Mocks the topology service to give paths in the test.
     */
    private class MockTopologyService extends TopologyServiceAdapter {
        Set<Path> paths = Sets.newHashSet(path);

        @Override
        public Topology currentTopology() {
            return null;
        }

        @Override
        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
            return paths;
        }
    }

    /**
     * Mocks the device service so that devices and ports appear available in the test.
     */
    private static class MockDeviceService extends DeviceServiceAdapter {
        @Override
        public boolean isAvailable(DeviceId deviceId) {
            return true;
        }

        @Override
        public List<Port> getPorts(DeviceId deviceId) {
            if (deviceId.equals(deviceId(DEV1))) {
                return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
            }

            if (deviceId.equals(deviceId(DEV2))) {
                return ImmutableList.of((Port) D2P1, (Port) D2P2);
            }

            if (deviceId.equals(deviceId(DEV3))) {
                return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
            }

            return Collections.emptyList();
        }

        @Override
        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
            if (deviceId.equals(deviceId(DEV1))) {
                switch (portNumber.toString()) {
                    case "1":
                        return D1P1;
                    case "2":
                        return D1P2;
                    case "3":
                        return D1P3;
                    default:
                        return null;
                }
            }
            if (deviceId.equals(deviceId(DEV2))) {
                switch (portNumber.toString()) {
                    case "1":
                        return D2P1;
                    case "2":
                        return D2P2;
                    default:
                        return null;
                }
            }
            if (deviceId.equals(deviceId(DEV3))) {
                switch (portNumber.toString()) {
                    case "1":
                        return D3P1;
                    case "2":
                        return D3P2;
                    case "3":
                        return D3P3;
                    default:
                        return null;
                }
            }
            return null;
        }
    }

    private static class MockDriverService extends DriverServiceAdapter
            implements DriverService {
        // TODO override to return appropriate driver,
        // with DefaultOpticalDevice support, etc.
    }

    @Before
    public void setUp() {
        AbstractProjectableModel.setDriverService(null, new MockDriverService());
        sut =  new OpticalOduIntentCompiler();
        coreService = createMock(CoreService.class);
        expect(coreService.registerApplication("org.onosproject.net.intent"))
                .andReturn(appId);
        sut.coreService = coreService;
        sut.deviceService = new MockDeviceService();
        sut.resourceService = new MockResourceService();
        sut.topologyService = new MockTopologyService();

        super.setUp();

        intentExtensionService = createMock(IntentExtensionService.class);
        intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
        intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
        sut.intentManager = intentExtensionService;

        replay(coreService, intentExtensionService);
    }

    /**
     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
     * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
     *   - only one TributarySlot is used
     */
    @Test
    public void test1GbeMultiplexOverOdu2() {

        intent = OpticalOduIntent.builder()
                .appId(APP_ID)
                .key(KEY1)
                .src(d1p1)
                .dst(d3p2)
                .signalType(D1P1.signalType())
                .bidirectional(false)
                .build();

        sut.activate();

        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
        assertThat(compiled, hasSize(1));

        assertThat("key is inherited",
                   compiled.stream().map(Intent::key).collect(Collectors.toList()),
                   everyItem(is(intent.key())));

        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();

        // 1st Device
        FlowRule rule1 = rules.stream()
                .filter(x -> x.deviceId().equals(device1.id()))
                .findFirst()
                .get();
        // validate SRC selector
        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
        selectorBuilder1.matchInPort(d1p1.port());
        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
        assertThat(rule1.selector(), is(selectorBuilder1.build()));

        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
        Set<TributarySlot> slots = new HashSet<>();
        slots.add(TributarySlot.of(1));
        OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
        treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
        treatmentBuilder1.setOutput(d1p2.port());
        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));

        // 2nd Device
        FlowRule rule2 = rules.stream()
                .filter(x -> x.deviceId().equals(device2.id()))
                .findFirst()
                .get();
        // validate SRC selector
        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
        selectorBuilder2.matchInPort(d2p1.port());
        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
        selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
        assertThat(rule2.selector(), is(selectorBuilder2.build()));

        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
        treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
        treatmentBuilder2.setOutput(d2p2.port());
        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));


        // 3rd Device
        FlowRule rule3 = rules.stream()
                .filter(x -> x.deviceId().equals(device3.id()))
                .findFirst()
                .get();
        // validate DST selector (with OduSignalId, where the same TributarySlot is used)
        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
        selectorBuilder3.matchInPort(d3p1.port());
        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
        selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
        assertThat(rule3.selector(), is(selectorBuilder3.build()));

        // validate DST treatment
        assertThat(rule3.treatment(), is(
                DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
                ));

        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
                intent.priority(), rule.priority()));

        sut.deactivate();
    }

    /**
     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
     * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
     *   - All TributarySlots are used
     */
    @Test
    public void test10GbeMultiplexOverOdu2() {

        intent = OpticalOduIntent.builder()
                .appId(APP_ID)
                .key(KEY1)
                .src(d1p3)
                .dst(d3p3)
                .signalType(D1P3.signalType())
                .bidirectional(false)
                .build();

        sut.activate();

        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
        assertThat(compiled, hasSize(1));

        assertThat("key is inherited",
                   compiled.stream().map(Intent::key).collect(Collectors.toList()),
                   everyItem(is(intent.key())));

        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();

        // 1st Device
        FlowRule rule1 = rules.stream()
                .filter(x -> x.deviceId().equals(device1.id()))
                .findFirst()
                .get();
        // validate SRC selector
        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
        selectorBuilder1.matchInPort(d1p3.port());
        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
        assertThat(rule1.selector(), is(selectorBuilder1.build()));

        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
        treatmentBuilder1.setOutput(d1p2.port());
        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));

        // 2nd Device
        FlowRule rule2 = rules.stream()
                .filter(x -> x.deviceId().equals(device2.id()))
                .findFirst()
                .get();
        // validate SRC selector
        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
        selectorBuilder2.matchInPort(d2p1.port());
        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
        assertThat(rule2.selector(), is(selectorBuilder2.build()));

        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
        treatmentBuilder2.setOutput(d2p2.port());
        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));


        // 3rd Device
        FlowRule rule3 = rules.stream()
                .filter(x -> x.deviceId().equals(device3.id()))
                .findFirst()
                .get();
        // validate DST selector (without OduSignalId - all TributarySlots are used)
        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
        selectorBuilder3.matchInPort(d3p1.port());
        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
        assertThat(rule3.selector(), is(selectorBuilder3.build()));

        // validate DST treatment
        assertThat(rule3.treatment(), is(
                DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
                ));

        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
                intent.priority(), rule.priority()));

        sut.deactivate();
    }

}