/*
 * 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.onlab.rest.BaseResource;
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.*;

/**
 * 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);
        BaseResource.setServiceDirectory(testDirectory);
        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);
//    }
}
