/*
 * 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;

import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.Path;

import com.google.common.testing.EqualsTester;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.net.NetTestTools.createPath;

public class OpticalPathIntentTest extends AbstractIntentTest {

    static final int PRIORITY = 777;

    OpticalPathIntent intent1;
    OpticalPathIntent intent2;
    Path defaultPath;

    @Before
    public void opticalPathIntentTestSetUp() {
        defaultPath = createPath("a", "b", "c");
        intent1 = OpticalPathIntent.builder()
                .appId(APP_ID)
                .src(connectPoint("one", 1))
                .dst(connectPoint("two", 2))
                .path(defaultPath)
                .priority(PRIORITY)
                .build();

        intent2 = OpticalPathIntent.builder()
                .appId(APP_ID)
                .src(connectPoint("two", 1))
                .dst(connectPoint("one", 2))
                .path(defaultPath)
                .priority(PRIORITY)
                .build();
    }

    /**
     * Checks that the OpticalPathIntent class is immutable.
     */
    @Test
    public void testImmutability() {
        assertThatClassIsImmutable(OpticalPathIntent.class);
    }

    /**
     * Checks the operation of equals(), hashCode() and toString() methods.
     */
    @Test
    public void testEquals() {
        new EqualsTester()
                .addEqualityGroup(intent1)
                .addEqualityGroup(intent2)
                .testEquals();
    }

    /**
     * Checks that the optical path ntent objects are created correctly.
     */
    @Test
    public void testContents() {
        assertThat(intent1.appId(), equalTo(APP_ID));
        assertThat(intent1.src(), Matchers.equalTo(connectPoint("one", 1)));
        assertThat(intent1.dst(), Matchers.equalTo(connectPoint("two", 2)));
        assertThat(intent1.priority(), is(PRIORITY));
        assertThat(intent1.path(), is(defaultPath));
    }
}
