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

import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.AbstractIntentTest;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.intent.constraint.LambdaConstraint;
import org.onosproject.net.resource.Bandwidth;
import org.onosproject.net.resource.Lambda;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.fail;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.net.intent.IntentTestsMocks.MockResourceService.makeBandwidthResourceService;
import static org.onosproject.net.intent.IntentTestsMocks.MockResourceService.makeLambdaResourceService;

/**
 * Unit tests for calculating paths for intents with constraints.
 */

public class PathConstraintCalculationTest extends AbstractIntentTest {

    private final IntentTestsMocks.MockSelector selector = new IntentTestsMocks.MockSelector();
    private final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
    private final ConnectPoint d1p1 = connectPoint("s1", 0);
    private final ConnectPoint d2p0 = connectPoint("s2", 0);
    private final ConnectPoint d2p1 = connectPoint("s2", 1);
    private final ConnectPoint d3p1 = connectPoint("s3", 1);
    private final ConnectPoint d3p0 = connectPoint("s3", 10);
    private final ConnectPoint d1p0 = connectPoint("s1", 10);

    private PathIntentInstaller sut;

    @Before
    public void setUpIntentInstaller() {
        sut = new PathIntentInstaller();
        sut.appId = APP_ID;
    }

    private PathIntent createPathIntent(List<Link> links, List<Constraint> constraints) {
        int hops = links.size() - 1;
        return new PathIntent(APP_ID, selector, treatment,
                              new DefaultPath(PID, links, hops), constraints);
    }

    /**
     * Tests that installation of bandwidth constrained path intents are
     * successful.
     */
    @Test
    public void testInstallBandwidthConstrainedIntentSuccess() {

        final Constraint constraint = new BandwidthConstraint(Bandwidth.bps(100.0));

        List<Link> links = Arrays.asList(
                createEdgeLink(d1p0, true),
                new DefaultLink(PID, d1p1, d2p0, DIRECT),
                new DefaultLink(PID, d2p1, d3p1, DIRECT),
                createEdgeLink(d3p0, false)
        );
        PathIntent installable = createPathIntent(links, Arrays.asList(constraint));

        sut.resourceService = makeBandwidthResourceService(1000.0);

        final List<Collection<FlowRuleOperation>> flowOperations = sut.install(installable);

        assertThat(flowOperations, notNullValue());
        assertThat(flowOperations, hasSize(1));
    }

    /**
     * Tests that installation of bandwidth constrained path intents fail
     * if there are no available resources.
     */
    @Test
    public void testInstallBandwidthConstrainedIntentFailure() {

        final Constraint constraint = new BandwidthConstraint(Bandwidth.bps(100.0));

        List<Link> links = Arrays.asList(
                createEdgeLink(d1p0, true),
                new DefaultLink(PID, d1p1, d2p0, DIRECT),
                new DefaultLink(PID, d2p1, d3p1, DIRECT),
                createEdgeLink(d3p0, false)
        );
        PathIntent installable = createPathIntent(links, Arrays.asList(constraint));

        // Make it look like the available bandwidth was consumed
        final IntentTestsMocks.MockResourceService resourceService = makeBandwidthResourceService(1000.0);
        resourceService.setAvailableBandwidth(1.0);
        sut.resourceService = resourceService;

        try {
            sut.install(installable);
            fail("Bandwidth request with no available bandwidth did not fail.");
        } catch (IntentTestsMocks.MockedAllocationFailure failure) {
            assertThat(failure,
                       instanceOf(IntentTestsMocks.MockedAllocationFailure.class));
        }
    }

    /**
     * Tests that installation of lambda constrained path intents are
     * successful.
     */
    @Test
    public void testInstallLambdaConstrainedIntentSuccess() {

        final Constraint constraint = new LambdaConstraint(Lambda.valueOf(1));

        List<Link> links = Arrays.asList(
                createEdgeLink(d1p0, true),
                new DefaultLink(PID, d1p1, d2p0, DIRECT),
                new DefaultLink(PID, d2p1, d3p1, DIRECT),
                createEdgeLink(d3p0, false)
        );
        PathIntent installable = createPathIntent(links, Arrays.asList(constraint));

        sut.resourceService = makeLambdaResourceService(1);

        final List<Collection<FlowRuleOperation>> flowOperations = sut.install(installable);

        assertThat(flowOperations, notNullValue());
        assertThat(flowOperations, hasSize(1));
    }

    /**
     * Tests that installation of lambda constrained path intents fail
     * if there are no available resources.
     */
    @Test
    public void testInstallLambdaConstrainedIntentFailure() {

        final Constraint constraint = new LambdaConstraint(Lambda.valueOf(1));

        List<Link> links = Arrays.asList(
                createEdgeLink(d1p0, true),
                new DefaultLink(PID, d1p1, d2p0, DIRECT),
                new DefaultLink(PID, d2p1, d3p1, DIRECT),
                createEdgeLink(d3p0, false)
        );
        PathIntent installable = createPathIntent(links, Arrays.asList(constraint));

        // Make it look like the available lambda was consumed
        final IntentTestsMocks.MockResourceService resourceService = makeLambdaResourceService(1);
        resourceService.setAvailableLambda(0);
        sut.resourceService = resourceService;

        try {
            sut.install(installable);
            fail("Lambda request with no available lambda did not fail.");
        } catch (IntentTestsMocks.MockedAllocationFailure failure) {
            assertThat(failure,
                       instanceOf(IntentTestsMocks.MockedAllocationFailure.class));
        }
    }

}
