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

import java.util.*;

import org.eclipse.persistence.history.*;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
import org.eclipse.persistence.testing.models.employee.domain.Project;

/**
 * <b>Purpose:</b>Tests rolling back objects to past state using history.
 * <p>
 * This test also acts as a kind of reset method, as tables can continually
 * be rolled back to a starting state.
 */

public class RollbackObjectsTest extends AutoVerifyTestCase {

    Class domainClass;
    AsOfClause pastTime;
    Vector pastObjects;

    public RollbackObjectsTest(Class domainClass, AsOfClause pastTime) {
        super();
        this.domainClass = domainClass;
        this.pastTime = pastTime;
    }

    @Override
    public void setup() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
    }

    @Override
    public void test() {
        org.eclipse.persistence.sessions.Session hs = getSession().acquireHistoricalSession(pastTime);
        pastObjects = hs.readAllObjects(domainClass);
        //getSession().getProject().checkDatabaseForDoesExist();

        Vector currentProjects = getSession().readAllObjects(Project.class);
        for (Enumeration enumtr = currentProjects.elements(); enumtr.hasMoreElements();) {
            ((Project)enumtr.nextElement()).getTeamLeader();
        }

            UnitOfWork uow = getSession().acquireUnitOfWork();

        for (Enumeration enumtr = pastObjects.elements(); enumtr.hasMoreElements();) {
            Employee emp = (Employee)enumtr.nextElement();
            emp.getProjects();
            for (Enumeration proj = emp.getProjects().elements(); proj.hasMoreElements();) {
                ((Project)proj.nextElement()).getTeamLeader();
            }
            emp.getAddress();
        }
        for (Enumeration enumtr = pastObjects.elements(); enumtr.hasMoreElements();) {
            Employee emp = (Employee)enumtr.nextElement();
            uow.registerObject(emp);
        }

        Vector pastProjects = hs.readAllObjects(Project.class);
        for (Enumeration enumtr = pastProjects.elements(); enumtr.hasMoreElements();) {
            Project project = (Project)enumtr.nextElement();
            uow.registerObject(project);
            uow.deepMergeClone(project);
        }
            //uow.registerAllObjects(pastProjects);
            //clone = uow.deepClone(obj);
            //} else {
            //    clone = uow.deepMergeClone(obj);
            //}
            uow.commit();
    }

    @Override
    public void verify() {
        try {
            Vector restoredObjects = getSession().readAllObjects(domainClass);
            if (restoredObjects.size() != pastObjects.size()) {
                throw new TestErrorException("Not all objects were restored.  Restored: " + restoredObjects.size() + " Total: " + pastObjects.size());
            }
        } finally {
            pastObjects = null;
        }
    }

    @Override
    public void reset() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
    }
}
