/*
 * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     05/11/2015-2.7 Tomas Kraus
//       - Initial API and implementation.
package org.eclipse.persistence.testing.tests.jpa;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.exceptions.ServerPlatformException;
import org.eclipse.persistence.internal.jpa.IsolatedHashMap;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Tests partition isolated {@link HashMap}.
 */
public class IsolatedHashMapTest extends JUnitTestCase {

    /** Session name and partition ID separator. */
    private static final char SEPARATOR = '$';

    /** Default short enough partition ID when server does not support partitions.*/
    private static final String DEFAULT_PARTITION_ID = "0";

    /** Tested map shall be stared trough whole JVM to run test against the same map for all configured partitions. */
    private static final Map<String, String> map = IsolatedHashMap.newMap();

    /** Detected server platform. */
    private static final ServerPlatform serverPlatform;

    /** Does platform support partitions? */
    private static final boolean supportPartitions;

    /** Session name templates used to generate session names in the tests. */
    private static final String[] sessionNameTemplates = {
        "", "0", "mySession", "EclipseLink"
    };

    /** Class initialization code. */
    static {
        String platformClass = ServerPlatformUtils.detectServerPlatform(null);
        ServerPlatform sp = null;
        try {
            sp = platformClass != null
                    ? ServerPlatformUtils.createServerPlatform(null, platformClass, SessionManager.class.getClassLoader())
                    : null;
        } catch (ServerPlatformException e) {
        }
        serverPlatform = sp;
        // False value also handles case when serverPlatform is null to avoid
        // NPE.
        supportPartitions = serverPlatform != null ? serverPlatform.usesPartitions() : false;
    }

    /**
     * Creates jUnit test suite for partition isolated {@link HashMap} tests.
     * @return new jUnit test suite containing all the tests.
     */
    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("IsolatedHashMapTest");
        suite.addTest(new IsolatedHashMapTest("testIsolationInRealContext"));
        return suite;
    }

    /**
     * Initialize session names in current partition context.
     * Test initialization helper.
     * @param partitionId Current partition ID. Shall not be {@code null}.
     */
     private static String[] initSessionNames(final String partitionId) {
         final int count = sessionNameTemplates.length;
         final String[] sessionNames = new String[count];
         int maxLength = 0;
         // Calculate StringBuilder internal storage size to avoid resizing.
         for (int i = 0; i < count; i++) {
             final int sessionNameTemplateLength = sessionNameTemplates[i].length();
             if (sessionNameTemplateLength > maxLength) {
                 maxLength = sessionNameTemplateLength;
             }
         }
         maxLength += 1 + partitionId.length();
         final StringBuilder sb = new StringBuilder(maxLength);
         for (int i = 0; i < count; i++) {
             if (i > 0) {
                 sb.delete(0, sb.length() - 1);
             }
             sb.append(sessionNameTemplates[i]);
             sb.append(SEPARATOR);
             sb.append(partitionId);
             sessionNames[i] = sb.toString();
         }
         return sessionNames;
     }

     /**
     * Creates an instance of partition isolated {@link HashMap} test.
     */
    public IsolatedHashMapTest() {
        super();
    }

    /**
     * Creates an instance of partition isolated {@link HashMap} test.
     * @param name jUnit test name.
     */
    public IsolatedHashMapTest(final String name) {
        super(name);
    }

    /**
     * Do partition isolation check in current partition context.
     * @param partitionId Current partition ID that should be visible in {@code map}.
     */
    private static void doIsolationCheck(final Map<String, String> map, final String partitionId, final SessionLog log) {
        final String[] sessionNames = initSessionNames(partitionId);
        final Set<String> namesSet = new HashSet<>(sessionNames.length);
        log.log(SessionLog.INFO, "  Partition ID: " + partitionId);
        for (String sessionName : sessionNames) {
            log.log(SessionLog.INFO, "    Adding session name: " + sessionName);
            map.put(sessionName, sessionName);
            namesSet.add(sessionName);
        }
        // Map shall contain session names in current partition context only.
        final int mapSize = map.size();
        log.log(SessionLog.INFO, "  Checking map size: session names count = "
                + sessionNames.length + ", map size = " + mapSize );
        assertEquals("Map size does not match session names count.", sessionNames.length, mapSize);
        // Verify individual session names.
        for (String sessionName : map.keySet()) {
            log.log(SessionLog.INFO, "    Getting and checking session name: " + sessionName);
            assertTrue("Session name " + sessionName + "was not stored in current partition context.",
                    namesSet.contains(sessionName));
        }
    }

    /**
     * Test partition isolation in real context with real {@link ServerPlatform}.
     */
    public void testIsolationInRealContext() {
        final SessionLog log = getServerSession().getSessionLog();
        log.log(SessionLog.INFO, "IsolatedHashMapTest.testIsolationInRealContext()");
        doIsolationCheck(map, supportPartitions ? serverPlatform.getPartitionID() : DEFAULT_PARTITION_ID, log);
    }

}
