/*
 * Copyright 2017-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.impl;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestTools;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.IntentOperationContext;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.TestInstallableIntent;
import org.onosproject.store.intent.impl.IntentStoreAdapter;
import org.onosproject.store.service.WallClockTimestamp;

import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;

import static org.junit.Assert.*;

/**
 * Tests for install coordinator.
 */
public class InstallCoordinatorTest {
    private static final int INSTALL_DELAY = 100;
    private static final int INSTALL_DURATION = 1000;
    private static final IdGenerator ID_GENERATOR = new MockIdGenerator();

    private InstallCoordinator installCoordinator;
    private InstallerRegistry installerRegistry;
    private TestIntentStore intentStore;
    private TestIntentInstaller intentInstaller;


    @Before
    public void setup() {
        Intent.unbindIdGenerator(ID_GENERATOR);
        Intent.bindIdGenerator(ID_GENERATOR);
        installerRegistry = new InstallerRegistry();
        intentStore = new TestIntentStore();
        intentInstaller = new TestIntentInstaller();
        installerRegistry.registerInstaller(TestInstallableIntent.class, intentInstaller);

        installCoordinator = new InstallCoordinator(installerRegistry, intentStore);
    }

    @After
    public void tearDown() {
        installerRegistry.unregisterInstaller(TestInstallableIntent.class);
        Intent.unbindIdGenerator(ID_GENERATOR);
    }

    /**
     * Installs test Intents.
     */
    @Test
    public void testInstallIntent() {
        IntentData toInstall = new IntentData(createTestIntent(),
                                              IntentState.INSTALLING,
                                              new WallClockTimestamp());
        List<Intent> intents = Lists.newArrayList();
        IntStream.range(0, 10).forEach(val -> {
            intents.add(new TestInstallableIntent(val));
        });
        toInstall = new IntentData(toInstall, intents);
        installCoordinator.installIntents(Optional.empty(), Optional.of(toInstall));
        Intent toInstallIntent = toInstall.intent();
        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
            IntentData newData = intentStore.newData;
            assertEquals(toInstallIntent, newData.intent());
            assertEquals(IntentState.INSTALLED, newData.state());
            assertEquals(intents, newData.installables());
        });
    }

    /**
     * Uninstalls test Intents.
     */
    @Test
    public void testUninstallIntent() {
        IntentData toUninstall = new IntentData(createTestIntent(),
                                              IntentState.WITHDRAWING,
                                              new WallClockTimestamp());
        List<Intent> intents = Lists.newArrayList();

        IntStream.range(0, 10).forEach(val -> {
            intents.add(new TestInstallableIntent(val));
        });

        toUninstall = new IntentData(toUninstall, intents);

        installCoordinator.installIntents(Optional.of(toUninstall), Optional.empty());
        Intent toUninstallIntent = toUninstall.intent();
        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
            IntentData newData = intentStore.newData;
            assertEquals(toUninstallIntent, newData.intent());
            assertEquals(IntentState.WITHDRAWN, newData.state());
            assertEquals(ImmutableList.of(), newData.installables());
        });

    }

    /**
     * Do both uninstall and install test Intents.
     */
    @Test
    public void testUninstallAndInstallIntent() {
        IntentData toUninstall = new IntentData(createTestIntent(),
                                                IntentState.INSTALLED,
                                                new WallClockTimestamp());
        IntentData toInstall = new IntentData(createTestIntent(),
                                                IntentState.INSTALLING,
                                                new WallClockTimestamp());
        List<Intent> intentsToUninstall = Lists.newArrayList();
        List<Intent> intentsToInstall = Lists.newArrayList();

        IntStream.range(0, 10).forEach(val -> {
            intentsToUninstall.add(new TestInstallableIntent(val));
        });

        IntStream.range(10, 20).forEach(val -> {
            intentsToInstall.add(new TestInstallableIntent(val));
        });

        toUninstall = new IntentData(toUninstall, intentsToUninstall);
        toInstall = new IntentData(toInstall, intentsToInstall);

        installCoordinator.installIntents(Optional.of(toUninstall), Optional.of(toInstall));
        Intent toInstallIntent = toInstall.intent();

        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
            IntentData newData = intentStore.newData;
            assertEquals(toInstallIntent, newData.intent());
            assertEquals(IntentState.INSTALLED, newData.state());
            assertEquals(intentsToInstall, newData.installables());
        });
    }

    /**
     * Not uninstall nor install anything.
     */
    @Test
    public void testInstallNothing() {
        installCoordinator.installIntents(Optional.empty(), Optional.empty());
        assertNull(intentStore.newData);
    }

    /**
     * Test Intent install failed.
     */
    @Test
    public void testInstallFailed() {
        installerRegistry.unregisterInstaller(TestInstallableIntent.class);
        installerRegistry.registerInstaller(TestInstallableIntent.class, new TestFailedIntentInstaller());
        IntentData toUninstall = new IntentData(createTestIntent(),
                                                IntentState.INSTALLED,
                                                new WallClockTimestamp());
        IntentData toInstall = new IntentData(createTestIntent(),
                                              IntentState.INSTALLING,
                                              new WallClockTimestamp());
        List<Intent> intentsToUninstall = Lists.newArrayList();
        List<Intent> intentsToInstall = Lists.newArrayList();

        IntStream.range(0, 10).forEach(val -> {
            intentsToUninstall.add(new TestInstallableIntent(val));
        });

        IntStream.range(10, 20).forEach(val -> {
            intentsToInstall.add(new TestInstallableIntent(val));
        });

        toUninstall = new IntentData(toUninstall, intentsToUninstall);
        toInstall = new IntentData(toInstall, intentsToInstall);

        installCoordinator.installIntents(Optional.of(toUninstall), Optional.of(toInstall));

        Intent toUninstallIntent = toUninstall.intent();
        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
            IntentData newData = intentStore.newData;
            assertEquals(toUninstallIntent, newData.intent());
            assertEquals(IntentState.CORRUPT, newData.state());
            assertEquals(intentsToUninstall, newData.installables());
        });
    }

    /**
     * Creates a test Intent.
     *
     * @return the test Intent.
     */
    private PointToPointIntent createTestIntent() {
        FilteredConnectPoint ingress = new FilteredConnectPoint(ConnectPoint.deviceConnectPoint("s1/1"));
        FilteredConnectPoint egress = new FilteredConnectPoint(ConnectPoint.deviceConnectPoint("s1/2"));
        ApplicationId appId = TestApplicationId.create("test App");
        return PointToPointIntent.builder()
                .filteredIngressPoint(ingress)
                .filteredEgressPoint(egress)
                .appId(appId)
                .key(Key.of("Test key", appId))
                .build();
    }

    /**
     * Test Intent store; records the newest Intent data.
     */
    class TestIntentStore extends IntentStoreAdapter {
        IntentData newData;
        @Override
        public void write(IntentData newData) {
            this.newData = newData;
        }
    }

    /**
     * Test Intent installer; always success for every Intent operation.
     */
    class TestIntentInstaller implements IntentInstaller<TestInstallableIntent> {
        @Override
        public void apply(IntentOperationContext<TestInstallableIntent> context) {
            installCoordinator.success(context);
        }
    }

    /**
     * Test Intent installer; always failed for every Intent operation.
     */
    class TestFailedIntentInstaller implements IntentInstaller<TestInstallableIntent> {
        @Override
        public void apply(IntentOperationContext<TestInstallableIntent> context) {
            installCoordinator.failed(context);
        }
    }
}
