/*
 * 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.distributedservers.rcm;

import java.util.Hashtable;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.eclipse.persistence.sessions.coordination.TransportManager;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.testing.tests.distributedservers.DistributedServer;
import org.eclipse.persistence.testing.tests.distributedservers.DistributedServersModel;
import org.eclipse.persistence.testing.tests.isolatedsession.IsolatedEmployee;
import org.eclipse.persistence.testing.tests.isolatedsession.IsolatedSessionSystem;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
import org.eclipse.persistence.testing.models.employee.domain.PhoneNumber;
import org.eclipse.persistence.testing.models.optimisticlocking.OptimisticLockingSystem;
import org.eclipse.persistence.tools.schemaframework.PopulationManager;


public class RCMDistributedServersModel extends DistributedServersModel {
    public RCMDistributedServersModel() {
        setDescription("Tests cache synchronization with RCM.");
    }

    @Override
    public void addRequiredSystems() {
        super.addRequiredSystems();
        addRequiredSystem(new IsolatedSessionSystem());
        addRequiredSystem(new OptimisticLockingSystem());
    }

    /**
     * Factory method for a DistributedServer.  Overridden by subclasses;
     */
    @Override
    public DistributedServer createDistributedServer(Session session) {
        return new RCMDistributedServer((DatabaseSession)session);
    }

    @Override
    public void addTests() {
        super.addTests();
        PopulationManager manager = PopulationManager.getDefaultManager();
        Employee employee = (Employee)manager.getObject(Employee.class, "0001");

        Hashtable configurationHashtable = new Hashtable();
        configurationHashtable.put(Employee.class, Integer.valueOf(ClassDescriptor.INVALIDATE_CHANGED_OBJECTS));
        ConfigurableUpdateChangeObjectTest test = new ConfigurableUpdateChangeObjectTest(employee, configurationHashtable);
        test.setName("Update Change Employee - Invalidate Employee");
        test.setDescription("Test the invalidation setting on cache synchronization for Employee");
        addTest(test);

        configurationHashtable = new Hashtable();
        configurationHashtable.put(PhoneNumber.class, Integer.valueOf(ClassDescriptor.INVALIDATE_CHANGED_OBJECTS));
        configurationHashtable.put(Employee.class, Integer.valueOf(ClassDescriptor.INVALIDATE_CHANGED_OBJECTS));
        test = new ConfigurableUpdateChangeObjectTest(employee, configurationHashtable);
        test.setName("Update Change Employee - Invalidate Employee, Phone Number");
        test.setDescription("Test the invalidation setting on cache synchronization for Phone Number");
        addTest(test);

        addTest(new SendNewObjectCacheSyncTest(true));
        addTest(new SendNewObjectCacheSyncTest(false));
        addTest(new RelatedNewObjectCacheSyncTest());
        addTest(new MultipleCacheSyncTypeTest());
        addTest(new RelatedNewObjectNotSentTest());
        addTest(new DeleteObjectNotSentTest());
        addTest(new ChangeObjectNotSentTest());
        //Add the 2 tests below to verify bug 4194320
        //addTest(new InvalidCacheSyncTypeTest(-1));
        //addTest(new InvalidCacheSyncTypeTest(5));
        addTest(new IsolatedObjectNotSentTest());

        configurationHashtable = new Hashtable();
        configurationHashtable.put(IsolatedEmployee.class, Integer.valueOf(ClassDescriptor.SEND_OBJECT_CHANGES));
        IsolatedObjectNotSentTest atest = new IsolatedObjectNotSentTest(configurationHashtable);
        atest.setName("IsolatedObjectNotSentTest - SEND_OBJECT_CHANGES");
        addTest(atest);

        configurationHashtable = new Hashtable();
        configurationHashtable.put(IsolatedEmployee.class, Integer.valueOf(ClassDescriptor.INVALIDATE_CHANGED_OBJECTS));
        atest = new IsolatedObjectNotSentTest(configurationHashtable);
        atest.setName("IsolatedObjectNotSentTest - INVALIDATE_CHANGED_OBJECTS");
        addTest(atest);

        configurationHashtable = new Hashtable();
        configurationHashtable.put(IsolatedEmployee.class, Integer.valueOf(ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES));
        atest = new IsolatedObjectNotSentTest(configurationHashtable);
        atest.setName("IsolatedObjectNotSentTest - SEND_NEW_OBJECTS_WITH_CHANGES");
        addTest(atest);

        configurationHashtable = new Hashtable();
        configurationHashtable.put(IsolatedEmployee.class, Integer.valueOf(ClassDescriptor.DO_NOT_SEND_CHANGES));
        atest = new IsolatedObjectNotSentTest(configurationHashtable);
        atest.setName("IsolatedObjectNotSentTest - DO_NOT_SEND_CHANGES");
        addTest(atest);

        addTest(new InvalidateObjectWithMissingReferenceTest());
        addTest(new UpdateObjectInvalidationTest());
        addTest(new NativeUpdateObjectInvalidationTest());
        addTest(new NewObjectWithOptimisticLockingTest());
        addTest(new OrderedListNewObjectTest());

    }

    @Override
    public void startCacheSynchronization() {
        RemoteCommandManager cm = new RemoteCommandManager((AbstractSession)getSession());

        // set propagate command synchronously for testing
        cm.setShouldPropagateAsynchronously(false);
        cm.getDiscoveryManager().setAnnouncementDelay(0);
        // ovewrite default to use RMI registry naming service
        cm.getTransportManager().setNamingServiceType(TransportManager.REGISTRY_NAMING_SERVICE);
        // set full rmi URL of local host
        cm.setUrl("rmi://localhost:1099");
        // turn on cache sync with RCM
        ((AbstractSession)getSession()).setShouldPropagateChanges(true);
        cm.setServerPlatform(getSession().getServerPlatform());

        cm.initialize();
        // Sleep to allow RCM to startup and find each session.
        try {
            Thread.sleep(2000);
        } catch (Exception ignore) {
        }
    }

    @Override
    public void stopCacheSynchronization() {
        ((AbstractSession)getSession()).getCommandManager().shutdown();
        ((AbstractSession)getSession()).setCommandManager(null);
    }
}
