/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.incubator.net.virtual.impl;

import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onosproject.TestApplicationId;
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.IdGenerator;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualDevice;
import org.onosproject.incubator.net.virtual.VirtualLink;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
import org.onosproject.incubator.store.virtual.impl.SimpleVirtualIntentStore;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.EncapsulationType;
import org.onosproject.net.Link;
import org.onosproject.net.NetTestTools;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.TestDeviceParams;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.FakeIntentManager;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.TestableIntentService;
import org.onosproject.net.intent.WorkPartitionService;
import org.onosproject.net.intent.WorkPartitionServiceAdapter;
import org.onosproject.net.intent.constraint.EncapsulationConstraint;
import org.onosproject.store.service.TestStorageService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * Junit tests for VirtualNetworkIntentService.
 */
@Ignore("deprecated prototype implementation")
public class VirtualNetworkIntentManagerTest extends TestDeviceParams {

    private final String tenantIdValue1 = "TENANT_ID1";
    private static final ApplicationId APP_ID =
            new TestApplicationId("MyAppId");

    private ConnectPoint cp1;
    private ConnectPoint cp2;
    private ConnectPoint cp3;
    private ConnectPoint cp4;
    private ConnectPoint cp5;
    private ConnectPoint cp6;
    private VirtualLink link1;
    private VirtualLink link2;
    private VirtualLink link3;
    private VirtualLink link4;
    private VirtualLink link5;
    private VirtualLink link6;

    private VirtualNetworkManager manager;
    private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
    private VirtualNetworkIntentStore intentStore;
    private CoreService coreService;
    private TestableIntentService intentService = new FakeIntentManager();
    private VirtualNetworkIntentManager vnetIntentService;
    private TestIntentCompiler compiler = new TestIntentCompiler();
    private IntentExtensionService intentExtensionService;
    private WorkPartitionService workPartitionService;
    private ServiceDirectory testDirectory;
    private TestListener listener = new TestListener();
    private static final int MAX_WAIT_TIME = 5;
    private static final int MAX_PERMITS = 1;
    private static Semaphore created;
    private static Semaphore withdrawn;
    private static Semaphore purged;

    @Before
    public void setUp() throws Exception {
        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
        intentStore = new SimpleVirtualIntentStore();

        coreService = new VirtualNetworkIntentManagerTest.TestCoreService();

        MockIdGenerator.cleanBind();

        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
        virtualNetworkManagerStore.activate();

        manager = new VirtualNetworkManager();
        manager.store = virtualNetworkManagerStore;
        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
        intentService.addListener(listener);

        // Register a compiler and an installer both setup for success.
        intentExtensionService = intentService;
        intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);

        created = new Semaphore(0, true);
        withdrawn = new Semaphore(0, true);
        purged = new Semaphore(0, true);

        workPartitionService = new WorkPartitionServiceAdapter();
        testDirectory = new TestServiceDirectory()
                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
                .add(IntentService.class, intentService)
                .add(WorkPartitionService.class, workPartitionService);
        TestUtils.setField(manager, "serviceDirectory", testDirectory);

        manager.activate();
    }

    @After
    public void tearDown() {
        virtualNetworkManagerStore.deactivate();
        manager.deactivate();
        NetTestTools.injectEventDispatcher(manager, null);
        MockIdGenerator.unbind();
        intentService.removeListener(listener);
        created = null;
        withdrawn = null;
        purged = null;
    }

    /**
     * Method to create the virtual network for further testing.
     *
     * @return virtual network
     */
    private VirtualNetwork setupVirtualNetworkTopology() {
        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
        VirtualDevice virtualDevice1 =
                manager.createVirtualDevice(virtualNetwork.id(), DID1);
        VirtualDevice virtualDevice2 =
                manager.createVirtualDevice(virtualNetwork.id(), DID2);
        VirtualDevice virtualDevice3 =
                manager.createVirtualDevice(virtualNetwork.id(), DID3);
        VirtualDevice virtualDevice4 =
                manager.createVirtualDevice(virtualNetwork.id(), DID4);

        Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
        cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);

        Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
        cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);

        Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
        cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);

        Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
        cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);

        Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
        cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);

        Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
        cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);

        link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
        link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
        link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
        link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);

        vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
        vnetIntentService.intentStore = intentStore;
        return virtualNetwork;
    }

    /**
     * Tests the submit(), withdraw(), and purge() methods.
     */
    @Test
    public void testCreateAndRemoveIntent() {
        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();

        Key intentKey = Key.of("test", APP_ID);

        List<Constraint> constraints = new ArrayList<>();
        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));

        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
                .networkId(virtualNetwork.id())
                .key(intentKey)
                .appId(APP_ID)
                .ingressPoint(cp1)
                .egressPoint(cp5)
                .constraints(constraints)
                .build();
        // Test the submit() method.
        vnetIntentService.submit(virtualIntent);

        // Wait for the both intents to go into an INSTALLED state.
        try {
            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
                fail("Failed to wait for intent to get installed.");
            }
        } catch (InterruptedException e) {
            fail("Semaphore exception during intent installation." + e.getMessage());
        }

        // Test the getIntentState() method
        assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
                     vnetIntentService.getIntentState(virtualIntent.key()));

        // Test the withdraw() method.
        vnetIntentService.withdraw(virtualIntent);
        // Wait for the both intents to go into a WITHDRAWN state.
        try {
            if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
                fail("Failed to wait for intent to get withdrawn.");
            }
        } catch (InterruptedException e) {
            fail("Semaphore exception during intent withdrawal." + e.getMessage());
        }

        // Test the getIntentState() method
        assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
                     vnetIntentService.getIntentState(virtualIntent.key()));

        // Test the purge() method.
        vnetIntentService.purge(virtualIntent);
        // Wait for the both intents to be removed/purged.
        try {
            if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
                fail("Failed to wait for intent to get purged.");
            }
        } catch (InterruptedException e) {
            fail("Semaphore exception during intent purging." + e.getMessage());
        }

    }

    /**
     * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
     * isLocal() methods.
     */
    @Test
    public void testGetIntents() {
        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();

        Key intentKey = Key.of("test", APP_ID);

        List<Constraint> constraints = new ArrayList<>();
        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));

        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
                .networkId(virtualNetwork.id())
                .key(intentKey)
                .appId(APP_ID)
                .ingressPoint(cp1)
                .egressPoint(cp5)
                .constraints(constraints)
                .build();
        // Test the submit() method.
        vnetIntentService.submit(virtualIntent);

        // Wait for the both intents to go into an INSTALLED state.
        try {
            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
                fail("Failed to wait for intent to get installed.");
            }
        } catch (InterruptedException e) {
            fail("Semaphore exception during intent installation." + e.getMessage());
        }

        // Test the getIntents() method
        assertEquals("The intents size did not match as expected.", 1,
                     Iterators.size(vnetIntentService.getIntents().iterator()));

        // Test the getIntent() method
        assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));

        // Test the getIntentData() method
        assertEquals("The intent data size did not match as expected.", 1,
                     Iterators.size(vnetIntentService.getIntentData().iterator()));

        // Test the getIntentCount() method
        assertEquals("The intent count did not match as expected.", 1,
                     vnetIntentService.getIntentCount());

        // Test the isLocal() method
        assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));

    }

    /**
     * Test listener to listen for intent events.
     */
    private static class TestListener implements IntentListener {

        @Override
        public void event(IntentEvent event) {
            switch (event.type()) {
                case INSTALLED:
                    // Release one permit on the created semaphore since the Intent event was received.
//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
                    created.release();
                    break;
                case WITHDRAWN:
                    // Release one permit on the removed semaphore since the Intent event was received.
//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
                    withdrawn.release();
                    break;
                case PURGED:
                    // Release one permit on the purged semaphore since the Intent event was received.
                    purged.release();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Core service test class.
     */
    private class TestCoreService extends CoreServiceAdapter {

        @Override
        public IdGenerator getIdGenerator(String topic) {
            return new IdGenerator() {
                private AtomicLong counter = new AtomicLong(0);

                @Override
                public long getNewId() {
                    return counter.getAndIncrement();
                }
            };
        }
    }

    private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
        @Override
        public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
            return Lists.newArrayList(new MockInstallableIntent());
        }
    }

    private static class MockInstallableIntent extends FlowRuleIntent {

        public MockInstallableIntent() {
            super(APP_ID, null, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)),
                    Collections.emptyList(), PathIntent.ProtectionType.PRIMARY, null);
        }
    }

//    private void addOrUpdateIntent(Intent intent, IntentState state) {
//        checkNotNull(intent, "Intent cannot be null");
//        IntentData intentData = intentStore.(intent.key());
//        if (intentData == null) {
//            intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
//        } else {
//            intentData = new IntentData(intent, state, intentData.version());
//        }
//        intentKeyIntentDataMap.put(intent.key(), intentData);
//    }
}
