/*
 * Copyright 2014-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.intent;

import java.util.Arrays;
import java.util.Collections;

import org.junit.Test;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.NetTestTools;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.provider.ProviderId;

import static org.junit.Assert.assertEquals;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;

public class PathIntentTest extends ConnectivityIntentTest {
    // 111:11 --> 222:22
    private static final Path PATH1 = NetTestTools.createPath("111", "222");

    // 111:11 --> 333:33
    private static final Path PATH2 = NetTestTools.createPath("222", "333");

    private final ProviderId provider1 = new ProviderId("of", "1");
    private final DeviceId device1 = deviceId("1");
    private final DeviceId device2 = deviceId("2");
    private final PortNumber port1 = portNumber(1);
    private final PortNumber port2 = portNumber(2);
    private final PortNumber port3 = portNumber(3);
    private final PortNumber port4 = portNumber(4);
    private final ConnectPoint cp1 = new ConnectPoint(device1, port1);
    private final ConnectPoint cp2 = new ConnectPoint(device1, port2);
    private final ConnectPoint cp3 = new ConnectPoint(device2, port3);
    private final ConnectPoint cp4 = new ConnectPoint(device2, port4);
    private final DefaultLink link1 = DefaultLink.builder()
            .providerId(provider1)
            .src(cp1)
            .dst(cp2)
            .type(DIRECT)
            .build();
    private final DefaultLink link2 = DefaultLink.builder()
            .providerId(provider1)
            .src(cp1)
            .dst(cp2)
            .type(DIRECT)
            .build();
    private final double cost = 1;

    @Test
    public void basics() {
        PathIntent intent = createOne();
        assertEquals("incorrect id", APPID, intent.appId());
        assertEquals("incorrect match", MATCH, intent.selector());
        assertEquals("incorrect action", NOP, intent.treatment());
        assertEquals("incorrect path", PATH1, intent.path());
        assertEquals("incorrect key", KEY, intent.key());
    }

    @Override
    protected PathIntent createOne() {
        return PathIntent.builder()
                .appId(APPID)
                .key(KEY)
                .selector(MATCH)
                .treatment(NOP)
                .path(PATH1)
                .build();
    }

    @Override
    protected PathIntent createAnother() {
        return PathIntent.builder()
                .appId(APPID)
                .selector(MATCH)
                .treatment(NOP)
                .path(PATH2)
                .build();
    }

    /**
     * Tests the constructor raises IllegalArgumentException when the same device is specified in
     * source and destination of a link.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testRaiseExceptionWhenSameDevices() {
        PathIntent.builder()
                .appId(APPID)
                .selector(MATCH)
                .treatment(NOP)
                .path(new DefaultPath(provider1, Collections.singletonList(link1), cost))
                .build();
    }

    /**
     * Tests the constructor raises IllegalArgumentException when the different elements are specified
     * in source element of the first link and destination element of the second link.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testRaiseExceptionWhenDifferentDevice() {
        PathIntent.builder()
                .appId(APPID)
                .selector(MATCH)
                .treatment(NOP)
                .path(new DefaultPath(provider1, Arrays.asList(link1, link2), cost))
                .build();
    }

}
