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

/**
 * Register an object in an identity map by the primary key of that object. <p>
 * No exceptions should be thrown when registering an object in an identity map.
 */
public class RegisterInIdentityMapTest extends TestCase {
    protected Class identityMapClass;
    protected Class originalIdentityMapClass;
    protected int originalIdentityMapSize;
    protected Vector employees;

    public RegisterInIdentityMapTest(Class mapClass) {
        identityMapClass = mapClass;
    }

    /**
     * Test the the cached employees exist in the identity map and that the rest do not.
     */
    public void checkIdentityMap(Vector cachedEmployees) {
        if (getIdentityMap().getSize() != cachedEmployees.size()) {
            throw new TestErrorException("Unexpected identity map size, expecting:  " + cachedEmployees.size() + " found: " + getIdentityMap());
        }
        for (Enumeration enumtr = employees.elements(); enumtr.hasMoreElements();) {
            Object test = enumtr.nextElement();
            Object result = getObjectFromIdentityMap(test);

            if (cachedEmployees.contains(test) && (result != test)) {
                throw new TestErrorException("Test object: " + test + " did not match identity map object: " + result);
            }
            if (!cachedEmployees.contains(test) && (result != null)) {
                throw new TestErrorException("Found object: " + test + " which should not have been in the cache");
            }
        }
    }

    @Override
    public String getDescription() {
        return "This test verifies an object was properly registerted in the identity map";
    }

    /**
     * Return the identity map for the class Employee
     */
    protected IdentityMap getIdentityMap() {
        return getAbstractSession().getIdentityMapAccessorInstance().getIdentityMap(Employee.class);
    }

    protected Object getObjectFromIdentityMap(Object domainObject) {
        return getAbstractSession().getIdentityMapAccessorInstance().getFromIdentityMap(getSession().getId(domainObject), domainObject.getClass());
    }

    protected boolean isCacheIdentityMap() {
        return identityMapClass == CacheIdentityMap.class;
    }

    protected boolean isFullIdentityMap() {
        return identityMapClass == FullIdentityMap.class;
    }

    protected boolean isNoIdentityMap() {
        return identityMapClass == NoIdentityMap.class;
    }

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

        getSession().getDescriptor(Employee.class).setIdentityMapClass(identityMapClass);
        getSession().getDescriptor(Employee.class).setIdentityMapSize(10);
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
    }

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

    /**
     *    Reading all of the Employee objects from the database should place them in the identity map.
     */
    @Override
    public void test() {
        employees = getSession().readAllObjects(Employee.class);
    }

    @Override
    public void verify() {
        if (isNoIdentityMap()) {
            verifyNoIdentityMap();
        } else if (isCacheIdentityMap()) {
            verifyCacheIdentityMap();
        } else {
            // All others should have all objects and they are still referenced.
            verifyFullIdentityMap();
        }
    }

    /**
     * Verify that the last 10 elements exist in the cache.
     */
    public void verifyCacheIdentityMap() {
        Vector cache = (Vector)employees.clone();
        while (cache.size() > 10) {
            cache.removeElementAt(0);
        }
        checkIdentityMap(cache);
    }

    /**
     * For a FullIdentityMap all of the objects should have been cached and the size should be equal to the number of employees in the test pool.
     */
    public void verifyFullIdentityMap() {
        checkIdentityMap(employees);
    }

    /**
     * For NoIdentityMap there should have been no objects cached.
     */
    public void verifyNoIdentityMap() {
        checkIdentityMap(new Vector());
    }
}
