/*
 * 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.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.framework.*;

import org.eclipse.persistence.internal.identitymaps.*;
import org.eclipse.persistence.sessions.*;

/**
 * Bug 5840635
 * Ensure that adding a new CacheKey with a null object reference to
 * SoftCacheWeakIdentityMap during a phase of putting objects into the
 * IdentityMap does not result in the existing IdentityMap entries getting removed.
 * @author David Minsky
 */
public class CleanupCacheKeyCorrectnessTest extends TestCase {

    protected Class originalIdentityMapClass;
    protected Class newIdentityMapClass;
    protected int originalIdentityMapSize;
    protected int newIdentityMapSize;
    protected int numberOfObjectsToCreate;
    protected int objectsNotFoundInIdentityMap;

    public CleanupCacheKeyCorrectnessTest() {
        super();
        setDescription("This test verifies that CacheKeys with null object references aren't removed when calling IdentityMap.put()");
    }

    @Override
    public void setup() {
        originalIdentityMapClass = getSession().getDescriptor(Employee.class).getIdentityMapClass();
        originalIdentityMapSize = getSession().getDescriptor(Employee.class).getIdentityMapSize();

        newIdentityMapClass = SoftCacheWeakIdentityMap.class;
        newIdentityMapSize = 5;

        objectsNotFoundInIdentityMap = 0;
        numberOfObjectsToCreate = newIdentityMapSize * 5;

        getSession().getDescriptor(Employee.class).setIdentityMapClass(newIdentityMapClass);
        getSession().getDescriptor(Employee.class).setIdentityMapSize(newIdentityMapSize);

        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        beginTransaction();
    }

    /**
     * 1. Create and register multiple Employees with a UoW
     * 2. Commit UoW
     * 3. Check that the employees are contained in the parent session's
     *    IdentityMap; If they are not contained, increment the failure count
     */

    @Override
    public void test() {
        List<Employee> employees = new ArrayList<>(numberOfObjectsToCreate);

        UnitOfWork uow = getSession().acquireUnitOfWork();
        for (int i = 0; i < numberOfObjectsToCreate; i++) {
            int identifier = i + 1;
            Employee employee = new Employee();
            employees.add(employee); // add the original to the list for testing later
            employee.setFirstName("Bob");
            employee.setLastName("Jones#" + identifier);
            uow.registerObject(employee);
        }
        uow.commit();

        for (Iterator<Employee> iter = employees.iterator(); iter.hasNext();) {
            Employee employee = iter.next();
            // if the IdentityMap does not contain the employee object, increment failure count
            if (!getSession().getIdentityMapAccessor().containsObjectInIdentityMap(employee)) {
                objectsNotFoundInIdentityMap++;
            }
        }
    }

    @Override
    public void verify() {
        if (objectsNotFoundInIdentityMap > 0) {
            StringBuffer buffer = new StringBuffer();
            buffer.append("The IdentityMap - size(");
            buffer.append(newIdentityMapSize);
            buffer.append(") removed ");
            buffer.append(objectsNotFoundInIdentityMap);
            buffer.append(" new objects out of ");
            buffer.append(numberOfObjectsToCreate);
            buffer.append(" objects added. No objects should have been removed.");
            throw new TestErrorException(buffer.toString());
        }
    }

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

}
