/*
 * 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.security.store;

import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.security.store.SecurityModeState.*;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;

import org.junit.Before;
import org.junit.Test;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationRole;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.Version;
import org.onosproject.security.Permission;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

/**
 * Unit Test on DistributedSecurityModeStore.
 */
public class DistributedSecurityModeStoreTest {

    private final Logger log = getLogger(getClass());

    private DefaultApplicationId appId;
    private DefaultApplication app;

    private Permission testPermission;
    private Set<Permission> testPermissions;
    private List<String> testFeatures;
    private List<String> testRequiredApps;
    private Set<String> testLocations;
    private ConcurrentHashMap<String, Set<ApplicationId>> localBundleAppDirectory;
    private ConcurrentHashMap<ApplicationId, Set<String>> localAppBundleDirectory;
    private ConcurrentHashMap<ApplicationId, Set<Permission>> violations;
    private SecurityInfo testSecInfo;
    private ConcurrentHashMap<ApplicationId, SecurityInfo> states;

    private ExecutorService eventHandler;

    @Before
    public void setUp() throws Exception {
        appId = new DefaultApplicationId(1, "test");
        testPermissions = new HashSet<Permission>();
        testPermission = new Permission("testClass", "testName");
        testPermissions.add(testPermission);
        testFeatures = new ArrayList<String>();
        testFeatures.add("testFeature");
        testRequiredApps = new ArrayList<String>();
        testRequiredApps.add("testRequiredApp");
        app = new DefaultApplication(appId, Version.version(1, 1, "patch", "build"), "testTitle",
                "testDes", "testOri", "testCT",
                "testurl", "test", null,
                ApplicationRole.ADMIN, testPermissions,
                Optional.ofNullable(null), testFeatures, testRequiredApps);

        testLocations = new HashSet<String>();
        testLocations.add("locationA");
        testLocations.add("locationB");

        Set<ApplicationId> appIdSet = new HashSet<ApplicationId>();
        appIdSet.add(appId);
        localBundleAppDirectory = new ConcurrentHashMap<>();
        localBundleAppDirectory.put("testLocation", appIdSet);
        localAppBundleDirectory = new ConcurrentHashMap<>();
        localAppBundleDirectory.put(appId, testLocations);

        violations = new ConcurrentHashMap<ApplicationId, Set<Permission>>();
        violations.put(appId, testPermissions);

        testSecInfo = new SecurityInfo(testPermissions, SECURED);
        states = new ConcurrentHashMap<ApplicationId, SecurityInfo>();
        states.put(appId, testSecInfo);
    }

    @Test
    public void testActivate() {
        eventHandler = newSingleThreadExecutor(groupedThreads("onos/security/store", "event-handler", log));
        assertNotNull(eventHandler);
    }

    @Test
    public void testDeactivate() {
        eventHandler = newSingleThreadExecutor(groupedThreads("onos/security/store", "event-handler", log));
        eventHandler.shutdown();
        assertTrue(eventHandler.isShutdown());
    }

    @Test
    public void testGetBundleLocations() {
        Set<String> locations = localAppBundleDirectory.get(appId);
        assertTrue(locations.contains("locationA"));
    }

    @Test
    public void testGetApplicationIds() {
        Set<ApplicationId> appIds = localBundleAppDirectory.get("testLocation");
        assertTrue(appIds.contains(appId));
    }

    @Test
    public void testGetRequestedPermissions() {
        Set<Permission> permissions = violations.get(appId);
        assertTrue(permissions.contains(testPermission));
    }

    @Test
    public void testGetGrantedPermissions() {
        Set<Permission> permissions = states.get(appId).getPermissions();
        assertTrue(permissions.contains(testPermission));
    }

    @Test
    public void testRequestPermission() {
        states.compute(appId, (id, securityInfo) -> new SecurityInfo(securityInfo.getPermissions(), POLICY_VIOLATED));
        assertEquals(POLICY_VIOLATED, states.get(appId).getState());
        Permission testPermissionB = new Permission("testClassB", "testNameB");
        violations.compute(appId,
                (k, v) -> v == null ? Sets.newHashSet(testPermissionB) : addAndGet(v, testPermissionB));
        assertTrue(violations.get(appId).contains(testPermissionB));
    }

    private Set<Permission> addAndGet(Set<Permission> oldSet, Permission newPerm) {
        oldSet.add(newPerm);
        return oldSet;
    }

    @Test
    public void testIsSecured() {
        SecurityInfo info = states.get(appId);
        assertEquals(SECURED, info.getState());
    }

    @Test
    public void testReviewPolicy() {
        assertEquals(SECURED, states.get(appId).getState());
        states.computeIfPresent(appId, (applicationId, securityInfo) -> {
            if (securityInfo.getState().equals(SECURED)) {
                return new SecurityInfo(ImmutableSet.of(), REVIEWED);
            }
            return securityInfo;
        });
        assertEquals(REVIEWED, states.get(appId).getState());
    }

    @Test
    public void testAcceptPolicy() {
        assertEquals(SECURED, states.get(appId).getState());
        states.compute(appId,
                (id, securityInfo) -> {
                    switch (securityInfo.getState()) {
                        case POLICY_VIOLATED:
                            return new SecurityInfo(securityInfo.getPermissions(), SECURED);
                        case SECURED:
                            return new SecurityInfo(securityInfo.getPermissions(), POLICY_VIOLATED);
                        case INSTALLED:
                            return new SecurityInfo(securityInfo.getPermissions(), REVIEWED);
                        case REVIEWED:
                            return new SecurityInfo(securityInfo.getPermissions(), INSTALLED);
                        default:
                            return securityInfo;
                    }
                });
        assertEquals(POLICY_VIOLATED, states.get(appId).getState());
    }

    @Test
    public void testRegisterApplication() {
        states.remove(appId);
        assertNull(states.get(appId));

        for (String location : localAppBundleDirectory.get(appId)) {
            if (!localBundleAppDirectory.containsKey(location)) {
                localBundleAppDirectory.put(location, new HashSet<>());
            }
            if (!localBundleAppDirectory.get(location).contains(appId)) {
                localBundleAppDirectory.get(location).add(appId);
            }
        }
        states.put(appId, new SecurityInfo(Sets.newHashSet(), INSTALLED));
        assertNotNull(states.get(appId));
        assertEquals(INSTALLED, states.get(appId).getState());
    }

    @Test
    public void testUnregisterApplication() {
        if (localAppBundleDirectory.containsKey(appId)) {
            for (String location : localAppBundleDirectory.get(appId)) {
                if (localBundleAppDirectory.get(location) != null) {
                    if (localBundleAppDirectory.get(location).size() == 1) {
                        localBundleAppDirectory.remove(location);
                    } else {
                        localBundleAppDirectory.get(location).remove(appId);
                    }
                }
            }
            localAppBundleDirectory.remove(appId);
        }
        assertNull(localAppBundleDirectory.get(appId));
    }

    @Test
    public void testGetState() {
        assertEquals(SECURED, states.get(appId).getState());
    }

}
