/*
 * 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 org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.*;

/**
 * Test to make sure the reference cache of HardCacheWeakIdentityMap is properly maintained.
 * Although the way the maintenance takes place will be different for JDK 1.3 and JDK 1.4,
 * the end result should be the same.
 */
public class HardCacheWeakIdentityMapTest extends TestCase {
    protected Class<? extends IdentityMap> originalIdentityMapClass = null;
    protected int originalIdentityMapSize = 0;
    protected Employee firstEmployee = null;
    protected Employee secondEmployee = null;
    protected boolean firstEmployeeDropped = false;
    protected boolean referenceCacheSizeMaintained = false;
    public static final int REFERENCE_CACHE_SIZE = 10;

    public HardCacheWeakIdentityMapTest() {
    }

    @Override
    public void setup() {
        originalIdentityMapClass = getSession().getDescriptor(Employee.class).getIdentityMapClass();
        originalIdentityMapSize = getSession().getDescriptor(Employee.class).getIdentityMapSize();
        getSession().getDescriptor(Employee.class).setIdentityMapClass(HardCacheWeakIdentityMap.class);
        getSession().getDescriptor(Employee.class).setIdentityMapSize(REFERENCE_CACHE_SIZE);
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        beginTransaction();
    }

    @Override
    public void reset() {
        rollbackTransaction();
        getSession().getDescriptor(Employee.class).setIdentityMapClass(originalIdentityMapClass);
        getSession().getDescriptor(Employee.class).setIdentityMapSize(originalIdentityMapSize);
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
    }

    @Override
    public void test() {
        // insert and store two employees in a predictable order
        UnitOfWork uow = getSession().acquireUnitOfWork();
        firstEmployee = new Employee();
        firstEmployee.setFirstName("Test0");
        firstEmployee.setLastName("Employee");
        uow.registerObject(firstEmployee);
        uow.commit();

        uow = getSession().acquireUnitOfWork();
        Employee secondEmployee = new Employee();
        secondEmployee.setFirstName("Test1");
        secondEmployee.setLastName("Employee");
        uow.registerObject(secondEmployee);
        uow.commit();

        // insert 9 more employees to fill the subcache
        for (int i = 2; i < (REFERENCE_CACHE_SIZE + 1); i++) {
            uow = getSession().acquireUnitOfWork();
            Employee employee = (Employee)uow.registerObject(new Employee());
            employee.setFirstName("Test" + i);
            employee.setLastName("Employee");
            uow.commit();
        }

        HardCacheWeakIdentityMap map = (HardCacheWeakIdentityMap)getAbstractSession().getIdentityMapAccessorInstance().getIdentityMap(Employee.class);
        referenceCacheSizeMaintained = (map.getReferenceCache().size() == REFERENCE_CACHE_SIZE);
        firstEmployeeDropped = !map.getReferenceCache().contains(firstEmployee);

        // query the first employee to put him back in the sub cache
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(Employee.class);
        ExpressionBuilder employee = new ExpressionBuilder();
        Expression exp = employee.get("firstName").equal("Test0");
        query.setSelectionCriteria(exp);
        Employee queryResult = (Employee)getSession().executeQuery(query);

        referenceCacheSizeMaintained = (referenceCacheSizeMaintained && (map.getReferenceCache().size() == REFERENCE_CACHE_SIZE));
    }

    @Override
    public void verify() {
        HardCacheWeakIdentityMap map = (HardCacheWeakIdentityMap)getAbstractSession().getIdentityMapAccessorInstance().getIdentityMap(Employee.class);

        if (!referenceCacheSizeMaintained) {
            throw new TestErrorException("The HardCacheWeakIdentityMap sub-cache was not correctly maintained.  The reference cache size" + " was not correctly maintained.");
        }

        if (!firstEmployeeDropped) {
            throw new TestErrorException("The HardCacheWeakIdentityMap sub-cache was not correctly maintained.  An object was not" + " correctly dropped when the sub-cache was filled.");
        }

        if (!map.getReferenceCache().contains(firstEmployee)) {
            throw new TestErrorException("The HardCacheWeakIdentityMap sub-cache was not correctly maintained.  An object was not" + " correctly replaced when reread after being removed.");

        }

        if (map.getReferenceCache().contains(secondEmployee)) {
            throw new TestErrorException("The HardCacheWeakIdentityMap sub-cache was not correctly maintained.  An object was not" + " correctly removed when an object was reread.");
        }
    }
}
