/*
 * Copyright (c) 1998, 2021 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.identitymaps;

import java.util.*;
import org.eclipse.persistence.internal.helper.linkedlist.ExposedNodeLinkedList;
import org.eclipse.persistence.internal.identitymaps.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * Test the SoftCacheIdentityMap.
 * This test will throws warnings on problem, not error because of VM differences.
 */
public class ReadSoftCacheWeakIdentityMapTest extends ReadWeakIdentityMapTest {
    public ReadSoftCacheWeakIdentityMapTest(Class mapClass) {
        super(mapClass);
        setDescription("This test verifies that the SoftCacheWeakIdentityMap holds onto the SoftReferences appropriately");
    }

    @Override
    public void test() {
        if (getIdentityMap().getSize() == 0) {
            throw new TestWarningException("We did not fill the cache, the test is invalid.");
        }

        // Ensure subcache has correct references.
        ExposedNodeLinkedList list = ((SoftCacheWeakIdentityMap)getIdentityMap()).getReferenceCache();
        java.lang.ref.SoftReference ref = (java.lang.ref.SoftReference)list.getFirst();
        if (ref.get() == null) {
            throw new TestErrorException("Soft reference is null.");
        }
        ref = (java.lang.ref.SoftReference)list.getLast();
        if (ref.get() == null) {
            throw new TestErrorException("Soft reference is null.");
        }

        // The jdk1.2.0 on the Testing machine treats the weak reference as a softweak reference so we must waste memory
        Vector vector = new Vector(10000);
        for (int i = 0; i < 10000; ++i) {
            vector.addElement(new java.math.BigDecimal(i));
        }

        // Force garbage collection, which should clear the cache.
        System.gc();
        System.runFinalization();
        System.gc();
    }

    @Override
    public void verify() {
        // Ensure that some ref have garbage collected,
        // if not all through warning as different VM have different gc behavior.
        Map<Object, CacheKey> cache = getIdentityMap().getCacheKeys();
        int numObjects = 0;
        for (Iterator<CacheKey> iterator = cache.values().iterator(); iterator.hasNext();) {
            CacheKey key = (CacheKey)iterator.next();
            if (key.getObject() != null) {
                numObjects++;
            }
        }
        if (numObjects == querySize) {
            throw new TestWarningException("The SoftCacheWeakIdentityMap did not allow any garbage collection. This could be a VM thing");
        } else if (numObjects < (getIdentityMap().getMaxSize() / 2)) {
            throw new TestWarningException("The SoftCacheWeakIdentityMap garbage collected the soft cache. This may be because of VM differences.");
        }
    }
}
