/*
 * 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<Employee> employeeClass = Employee.class;
        Class<LargeProject> largeProjectClass = LargeProject.class;
        Class<SmallProject> 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<Employee> employeeClass = Employee.class;
        Class<LargeProject> largeProjectClass = LargeProject.class;
        Class<SmallProject> 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.");
        }
    }
}
