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

import java.util.List;
import java.util.Optional;

import org.hamcrest.Matchers;
import org.junit.Test;

import static org.junit.Assert.assertEquals;


import org.onlab.packet.MplsLabel;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.AbstractIntentTest;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MplsIntent;
import org.onosproject.net.intent.MplsPathIntent;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;

/**
 * Unit tests for the HostToHost intent compiler.
 */
public class MplsIntentCompilerTest extends AbstractIntentTest {

    private static final ApplicationId APPID = new TestApplicationId("foo");

    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();

    /**
     * Creates a PointToPoint intent based on ingress and egress device Ids.
     *
     * @param ingressIdString string for id of ingress device
     * @param egressIdString  string for id of egress device
     * @return PointToPointIntent for the two devices
     */
    private MplsIntent makeIntent(String ingressIdString,  Optional<MplsLabel> ingressLabel,
                                          String egressIdString, Optional<MplsLabel> egressLabel) {

        return MplsIntent.builder()
                .appId(APPID)
                .selector(selector)
                .treatment(treatment)
                .ingressPoint(connectPoint(ingressIdString, 1))
                .ingressLabel(ingressLabel)
                .egressPoint(connectPoint(egressIdString, 1))
                .egressLabel(egressLabel).build();
    }
    /**
     * Creates a compiler for HostToHost intents.
     *
     * @param hops string array describing the path hops to use when compiling
     * @return HostToHost intent compiler
     */
    private MplsIntentCompiler makeCompiler(String[] hops) {
        MplsIntentCompiler compiler =
                new MplsIntentCompiler();
        compiler.pathService = new IntentTestsMocks.MockPathService(hops);
        return compiler;
    }


    /**
     * Tests a pair of devices in an 8 hop path, forward direction.
     */
    @Test
    public void testForwardPathCompilation() {
        Optional<MplsLabel> ingressLabel = Optional.of(MplsLabel.mplsLabel(10));
        Optional<MplsLabel> egressLabel = Optional.of(MplsLabel.mplsLabel(20));

        MplsIntent intent = makeIntent("d1", ingressLabel, "d8", egressLabel);
        assertThat(intent, is(notNullValue()));

        String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
        MplsIntentCompiler compiler = makeCompiler(hops);
        assertThat(compiler, is(notNullValue()));

        List<Intent> result = compiler.compile(intent, null, null);
        assertThat(result, is(Matchers.notNullValue()));
        assertThat(result, hasSize(1));
        Intent forwardResultIntent = result.get(0);
        assertThat(forwardResultIntent instanceof MplsPathIntent, is(true));

        // if statement suppresses static analysis warnings about unchecked cast
        if (forwardResultIntent instanceof MplsPathIntent) {
            MplsPathIntent forwardPathIntent = (MplsPathIntent) forwardResultIntent;
            // 7 links for the hops, plus one default lnk on ingress and egress
            assertThat(forwardPathIntent.path().links(), hasSize(hops.length + 1));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d1", "d2"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d2", "d3"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d3", "d4"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d4", "d5"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d5", "d6"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d6", "d7"));
            assertThat(forwardPathIntent.path().links(), linksHasPath("d7", "d8"));
            assertEquals(forwardPathIntent.egressLabel(), egressLabel);
            assertEquals(forwardPathIntent.ingressLabel(), ingressLabel);
        }
    }

    /**
     * Tests a pair of devices in an 8 hop path, forward direction.
     */
    @Test
    public void testReversePathCompilation() {
        Optional<MplsLabel> ingressLabel = Optional.of(MplsLabel.mplsLabel(10));
        Optional<MplsLabel> egressLabel = Optional.of(MplsLabel.mplsLabel(20));

        MplsIntent intent = makeIntent("d8", ingressLabel, "d1", egressLabel);
        assertThat(intent, is(notNullValue()));

        String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
        MplsIntentCompiler compiler = makeCompiler(hops);
        assertThat(compiler, is(notNullValue()));

        List<Intent> result = compiler.compile(intent, null, null);
        assertThat(result, is(Matchers.notNullValue()));
        assertThat(result, hasSize(1));
        Intent reverseResultIntent = result.get(0);
        assertThat(reverseResultIntent instanceof MplsPathIntent, is(true));

        // if statement suppresses static analysis warnings about unchecked cast
        if (reverseResultIntent instanceof MplsPathIntent) {
            MplsPathIntent reversePathIntent = (MplsPathIntent) reverseResultIntent;
            assertThat(reversePathIntent.path().links(), hasSize(hops.length + 1));
            assertThat(reversePathIntent.path().links(), linksHasPath("d2", "d1"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d3", "d2"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d4", "d3"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d5", "d4"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d6", "d5"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d7", "d6"));
            assertThat(reversePathIntent.path().links(), linksHasPath("d8", "d7"));
            assertEquals(reversePathIntent.egressLabel(), egressLabel);
            assertEquals(reversePathIntent.ingressLabel(), ingressLabel);
        }
    }

    /**
     * Tests compilation of the intent which designates two different ports on the same switch.
     */
    @Test
    public void testSameSwitchDifferentPortsIntentCompilation() {
        ConnectPoint src = new ConnectPoint(deviceId("1"), portNumber(1));
        ConnectPoint dst = new ConnectPoint(deviceId("1"), portNumber(2));
        MplsIntent intent = MplsIntent.builder()
                .appId(APP_ID)
                .selector(selector)
                .treatment(treatment)
                .ingressPoint(src)
                .ingressLabel(Optional.empty())
                .egressPoint(dst)
                .egressLabel(Optional.empty())
                .build();

        String[] hops = {"1"};
        MplsIntentCompiler sut = makeCompiler(hops);

        List<Intent> compiled = sut.compile(intent, null, null);

        assertThat(compiled, hasSize(1));
        assertThat(compiled.get(0), is(instanceOf(MplsPathIntent.class)));
        Path path = ((MplsPathIntent) compiled.get(0)).path();

        assertThat(path.links(), hasSize(2));
        Link firstLink = path.links().get(0);
        assertThat(firstLink, is(createEdgeLink(src, true)));
        Link secondLink = path.links().get(1);
        assertThat(secondLink, is(createEdgeLink(dst, false)));
    }
}
