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

import java.lang.reflect.Field;

import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.internal.descriptors.PersistenceEntity;
import org.eclipse.persistence.internal.weaving.*;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.performance.*;
import org.eclipse.persistence.tools.schemaframework.PopulationManager;

/**
 * This model tests reading/writing using weaved performance employee model.
 */
public class EmployeeWeavingTestModel extends TestModel {

    public EmployeeWeavingTestModel() {
        setDescription("This model tests reading/writing using weaved performance employee model.");
    }

    @Override
    public void addRequiredSystems() {
        addRequiredSystem(new EmployeeSystem());
    }

    @Override
    public void addTests() {
        addTest(getWeaverTestSuite());
        addTest(getReadObjectTestSuite());
        addTest(getUpdateTestSuite());
        addTest(getInsertTestSuite());
        addTest(getReadAllTestSuite());
        addTest(getFetchGroupsTestSuite());
    }

    public TestSuite getInsertTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("EmployeeWeavedInsertTestSuite");
        suite.setDescription("This suite tests the insertion of each object in the employee weaved performance model.");
        EmployeePopulator system = new EmployeePopulator();

        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicEmployeeExample1()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicEmployeeExample2()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicEmployeeExample3()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicEmployeeExample4()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicEmployeeExample5()));

        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicSmallProjectExample1()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicSmallProjectExample2()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicSmallProjectExample3()));

        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicLargeProjectExample1()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicLargeProjectExample2()));
        suite.addTest(new UnitOfWorkBasicInsertObjectTest(system.basicLargeProjectExample3()));

        return suite;
    }

    public TestSuite getReadAllTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("EmployeeWeavedReadAllTestSuite");
        suite.setDescription("This suite tests the reading of all the objects of each class in the employee weaved performance model.");

        suite.addTest(new ReadAllTest(Employee.class, 12));
        suite.addTest(new ReadAllTest(Project.class, 15));
        suite.addTest(new ReadAllTest(LargeProject.class, 5));
        suite.addTest(new ReadAllTest(SmallProject.class, 10));

        return suite;
    }

    public TestSuite getReadObjectTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("EmployeeWeavedReadObjectTestSuite");
        suite.setDescription("This suite test the reading of each object in the employee weaved performance model.");

        Class employeeClass = Employee.class;
        Class largeProjectClass = LargeProject.class;
        Class smallProjectClass = SmallProject.class;
        PopulationManager manager = PopulationManager.getDefaultManager();

        suite.addTest(new ReadObjectTest(manager.getObject(employeeClass, "0001")));
        suite.addTest(new ReadObjectTest(manager.getObject(employeeClass, "0002")));
        suite.addTest(new ReadObjectTest(manager.getObject(employeeClass, "0003")));
        suite.addTest(new ReadObjectTest(manager.getObject(employeeClass, "0004")));
        suite.addTest(new ReadObjectTest(manager.getObject(employeeClass, "0005")));

        suite.addTest(new ReadObjectTest(manager.getObject(smallProjectClass, "0001")));
        suite.addTest(new ReadObjectTest(manager.getObject(smallProjectClass, "0002")));
        suite.addTest(new ReadObjectTest(manager.getObject(smallProjectClass, "0003")));

        suite.addTest(new ReadObjectTest(manager.getObject(largeProjectClass, "0001")));
        suite.addTest(new ReadObjectTest(manager.getObject(largeProjectClass, "0002")));
        suite.addTest(new ReadObjectTest(manager.getObject(largeProjectClass, "0003")));

        return suite;
    }

    public TestSuite getUpdateTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("EmployeeWeavedUpdateTestSuite");
        suite.setDescription("This suite tests the updating of each object in the employee demo.");

        Class employeeClass = Employee.class;
        Class largeProjectClass = LargeProject.class;
        Class smallProjectClass = SmallProject.class;
        PopulationManager manager = PopulationManager.getDefaultManager();

        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(employeeClass, "0001")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(employeeClass, "0002")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(employeeClass, "0003")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(employeeClass, "0004")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(employeeClass, "0005")));

        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(smallProjectClass, "0001")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(smallProjectClass, "0002")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(smallProjectClass, "0003")));

        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(largeProjectClass, "0001")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(largeProjectClass, "0002")));
        suite.addTest(new UnitOfWorkBasicUpdateObjectTest(manager.getObject(largeProjectClass, "0003")));

        return suite;
    }

    public TestSuite getWeaverTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("WeaverTestSuite");
        suite.setDescription("This suite tests that the weaver ran on the class files correctly.");

        suite.addTest(buildWeaverTest());
        return suite;
    }

    public TestSuite getFetchGroupsTestSuite() {
        TestSuite suite = new TestSuite();
        suite.setName("FetchGroupsTestSuite");
        suite.setDescription("This suite tests weaving of fetch groups.");

        suite.addTest(buildFetchGroupReadObjectTest());
        suite.addTest(buildFetchGroupReadAllTest());
        suite.addTest(buildFetchGroupReadObjectUOWTest());
        suite.addTest(buildFetchGroupReadObjectUOWTransactionTest());
        suite.addTest(buildFetchGroupUpdateObjectUOWTest());
        suite.addTest(buildFetchGroupUpdateNonFetchedObjectUOWTest());
        return suite;
    }

    public TestCase buildWeaverTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                testWeaving(new Employee(), true);
                testWeaving(new SmallProject(), true);
                testWeaving(new LargeProject(), true);
                testWeaving(new EmploymentPeriod(), false);
                testWeaving(new PhoneNumber(), true);
                testWeaving(new Address(), false);
                if ((new EmployeeSystem()) instanceof PersistenceWeaved) {
                    throwError("EmployeeSystem should not be weaved.");
                }
            }

            public void testWeaving(Object object, boolean indirection) {
                if (!(object instanceof PersistenceWeaved)) {
                    throwError("Object not weaved:" + object);
                }
                if ((object instanceof PersistenceWeavedLazy) != indirection) {
                    throwError("Object not weaved for indirection:" + object);
                }
                if (!(object instanceof ChangeTracker)) {
                    throwError("Object not weaved for ChangeTracker:" + object);
                }
                // Aggregate descriptors are stored on the mapping, nor weaved for PersistenceEntity.
                if (object instanceof EmploymentPeriod) {
                    if (!getSession().getDescriptor(Employee.class).getMappingForAttributeName("period").getReferenceDescriptor().getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
                        throwError("Descriptor not set to use change tracking:" + object);
                    }
                } else {
                    if (!getSession().getDescriptor(object).getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
                        throwError("Descriptor not set to use change tracking:" + object);
                    }
                    if (!(object instanceof PersistenceEntity)) {
                        throwError("Object not weaved for PersistenceEntity:" + object);
                    }
                    if (!(object instanceof FetchGroupTracker)) {
                        throwError("Object not weaved for FetchGroupTracker:" + object);
                    }
                }
            }
        };
        test.setName("WeaverTeest");
        return test;
    }

    /**
     * Test a basic fetch group read.
     */
    public TestCase buildFetchGroupReadObjectTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() throws Exception {
                Employee fetched = (Employee)getSession().readObject(Employee.class);
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadObjectQuery query = new ReadObjectQuery(fetched);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                query.setFetchGroup(fetchGroup);

                Employee partial = (Employee)getSession().executeQuery(query);
                verfiyFetchGroup(this, partial, fetched);
            }
        };
        test.setName("FetchGroupReadObjectTest");
        return test;
    }

    /**
     * Test a fetch group read in a unit of work.
     */
    public TestCase buildFetchGroupReadObjectUOWTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() throws Exception {
                Employee fetched = (Employee)getSession().readObject(Employee.class);
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadObjectQuery query = new ReadObjectQuery(fetched);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                query.setFetchGroup(fetchGroup);

                Employee partial = (Employee)getSession().acquireUnitOfWork().executeQuery(query);
                verfiyFetchGroup(this, partial, fetched);
            }
        };
        test.setName("FetchGroupReadObjectUOWTest");
        return test;
    }

    /**
     * Test a fetch group update in a unit of work.
     */
    public TestCase buildFetchGroupUpdateObjectUOWTest() {
        TestCase test = new TransactionalTestCase() {
            @Override
            public void test() throws Exception {
                Employee fetched = (Employee)getSession().readObject(Employee.class);
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadObjectQuery query = new ReadObjectQuery(fetched);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                query.setFetchGroup(fetchGroup);

                UnitOfWork uow = getSession().acquireUnitOfWork();
                Employee partial = (Employee)uow.executeQuery(query);
                partial.setFirstName("partial");
                uow.commit();
                fetched = (Employee)getSession().readObject(partial);
                if (!fetched.getFirstName().equals("partial")) {
                    throwError("Partial update not merged.");
                }
            }
        };
        test.setName("FetchGroupUpdateObjectUOWTest");
        return test;
    }

    /**
     * Test a fetch group update in a unit of work.
     */
    public TestCase buildFetchGroupUpdateNonFetchedObjectUOWTest() {
        TestCase test = new TransactionalTestCase() {
            @Override
            public void test() throws Exception {
                Employee fetched = (Employee)getSession().readObject(Employee.class);
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadObjectQuery query = new ReadObjectQuery(fetched);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                fetchGroup.addAttribute("address");
                query.setFetchGroup(fetchGroup);

                UnitOfWork uow = getSession().acquireUnitOfWork();
                Employee partial = (Employee)uow.executeQuery(query);
                partial.setSalary(1234);
                uow.commit();
                fetched = (Employee)getSession().readObject(partial);
                if (fetched.getSalary() != 1234) {
                    throwError("Partial update not merged.");
                }
            }
        };
        test.setName("FetchGroupUpdateNonFetchedObjectUOWTest");
        return test;
    }

    /**
     * Test a fetch group read in a unit of work early transaction.
     */
    public TestCase buildFetchGroupReadObjectUOWTransactionTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() throws Exception {
                Employee fetched = (Employee)getSession().readObject(Employee.class);
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadObjectQuery query = new ReadObjectQuery(fetched);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                fetchGroup.addAttribute("manager");
                query.setFetchGroup(fetchGroup);

                UnitOfWork uow = getSession().acquireUnitOfWork();
                uow.beginEarlyTransaction();
                try {
                    Employee partial = (Employee)uow.executeQuery(query);
                    verfiyFetchGroup(this, partial, fetched);
                } finally {
                    uow.release();
                }
            }
        };
        test.setName("FetchGroupReadObjectUOWTransactionTest");
        return test;
    }

    /**
     * Test a basic fetch group read.
     */
    public TestCase buildFetchGroupReadAllTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() throws Exception {
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                ReadAllQuery query = new ReadAllQuery(Employee.class);
                FetchGroup fetchGroup = new FetchGroup();
                fetchGroup.addAttribute("firstName");
                fetchGroup.addAttribute("lastName");
                fetchGroup.addAttribute("period");
                query.setFetchGroup(fetchGroup);

                List result = (List)getSession().executeQuery(query);
                for (Iterator iterator = result.iterator(); iterator.hasNext(); ) {
                    Employee partial = (Employee)iterator.next();
                    partial.getFirstName();
                    partial.getAddress().getCity();
                }
            }
        };
        test.setName("FetchGroupReadAllTest");
        return test;
    }

    /**
     * Helper verify method used to verify partially fetch objects (first/lastName).
     */
    public void verfiyFetchGroup(TestCase test, Employee partial, Employee fetched) throws Exception {
        Field firstNameField = Employee.class.getDeclaredField("firstName");
        firstNameField.setAccessible(true);
        if (!(fetched.getFirstName().equals(firstNameField.get(partial)))) {
            test.throwError("FirstName not fetch correctly.");
        }
        Field salaryField = Employee.class.getDeclaredField("salary");
        salaryField.setAccessible(true);
        if (((Number)salaryField.get(partial)).longValue() != 0) {
            test.throwError("Salary should not be fetched.");
        }
        if (!(partial.getFirstName().equals(fetched.getFirstName()))) {
            test.throwError("FirstName not fetch correctly.");
        }
        if (!(partial.getLastName().equals(fetched.getLastName()))) {
            test.throwError("LastName not fetch correctly.");
        }
        if (partial.getSalary() != fetched.getSalary()) {
            test.throwError("Salary not fetch correctly.");
        }
        if (!partial.getAddress().getCity().equals(fetched.getAddress().getCity())) {
            test.throwError("Address not fetch correctly.");
        }
    }
}
