/*******************************************************************************
 * Copyright (c) 2005, 2009 SAP. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     SAP - initial API and implementation
 ******************************************************************************/

package org.eclipse.persistence.testing.tests.wdf.jpa1.relation;

import static junit.framework.Assert.assertTrue;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.persistence.Cache;
import javax.persistence.EntityManager;

import org.eclipse.persistence.testing.framework.wdf.Bugzilla;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Bicycle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.CostCenter;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Cubicle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.CubiclePrimaryKeyClass;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.MotorVehicle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Project;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.TravelProfile;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Vehicle;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

/**
 * Testing relations in combination with object cache. Test cases generated by all-pairs testing tool: <li>ToManyFK, eager,
 * owning side right, cacheable both: testCostCenterEmployee</li> <li>ToOneFK, lazy, owning side left, cacheable right:
 * testMotorVehicleEmployee</li> <li>ToOneFK, eager, owning side right, cacheable both: testCubicleEmployee</li> <li>
 * ToManyJoinTable, eager, owning side left, cacheable right: testBicycleEmployee</li> <li>ToManyJoinTable, lazy, owning side
 * left, cacheable both: testEmployeeProject</li> <li>ToManyFK, lazy, owning side right, cacheable right: n.a.</li> <li>
 * ToManyJoinTable, lazy, owning side right, cacheable right: testTravelProfileVehicle</li>
 * 
 * 
 * 
 * <li>ToManyJoinTable, lazy, owning side right, cacheable both: testProjectEmployee</li> <li>ToManyJoinTable, lazy, owning side
 * left, cacheable left: testEmployeePatent</li> <li>ToOneFK, eager, owning side left, cacheable left: testEmployeeTravelProfile
 * </li> <li>ToManyFK, eager, owning side right, cacheable right</li> </ul>
 */
public class TestRelationshipsWithCache extends JPA1Base {

    /**
     * Test case: CostCenter.employees
     * <p>
     * Relationship mapping: ToManyFK, FetchType: eager, owning side: right, cacheable: both
     */
    @Test
    @Bugzilla(bugid=309681)
    public void testCostCenterEmployee() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();

        int costCenterId = 1;
        CostCenter costCenter = new CostCenter(1, "lotsOfMoney");
        int employeeId1 = 1;
        int employeeId2 = 2;
        Employee employee1 = new Employee(employeeId1, "very", "expensive", null);
        Employee employee2 = new Employee(employeeId2, "even", "moreExpensive", null);
        costCenter.addEmployee(employee1);
        costCenter.addEmployee(employee2);
        employee1.setCostCenter(costCenter);
        employee2.setCostCenter(costCenter);
        try {
            env.beginTransaction(em);
            em.persist(costCenter);
            em.persist(employee1);
            em.persist(employee2);
            env.commitTransactionAndClear(em);

            em.find(CostCenter.class, costCenterId); // eager loading of Employees
            assertTrue(cache.contains(CostCenter.class, costCenterId));
            assertTrue(cache.contains(Employee.class, employeeId1));
            assertTrue(cache.contains(Employee.class, employeeId2));

            env.beginTransaction(em);
            costCenter = em.find(CostCenter.class, costCenterId);
            employee1 = em.find(Employee.class, employeeId1);
            employee2 = em.find(Employee.class, employeeId2);
            List<Employee> foundEmployees = costCenter.getEmployees();
            assertTrue(foundEmployees != null);
            assertTrue("wrong number of riders: " + foundEmployees.size(), foundEmployees.size() == 2);
            if (foundEmployees.get(0).getId() == employeeId1) {
                assertTrue("wrong rider: " + foundEmployees.get(1).getId(), foundEmployees.get(1).getId() == employeeId2);
            } else {
                assertTrue("wrong rider: " + foundEmployees.get(0).getId(), foundEmployees.get(0).getId() == employeeId2);
                assertTrue("wrong rider: " + foundEmployees.get(1).getId(), foundEmployees.get(1).getId() == employeeId1);
            }
            CostCenter costCenter1 = employee1.getCostCenter();
            CostCenter costCenter2 = employee2.getCostCenter();
            assertTrue(costCenter1 != null);
            assertTrue(costCenter1.getId() == costCenterId);
            assertTrue(costCenter2 != null);
            assertTrue(costCenter2.getId() == costCenterId);
            costCenter.setEmployees(null);
            employee1.setCostCenter(null);
            employee2.setCostCenter(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(CostCenter.class, costCenterId));
            assertTrue(!cache.contains(Employee.class, employeeId1));
            assertTrue(!cache.contains(Employee.class, employeeId2));
            costCenter = em.find(CostCenter.class, costCenterId);
            employee1 = em.find(Employee.class, employeeId1);
            employee2 = em.find(Employee.class, employeeId2);
            assertTrue(costCenter.getEmployees().size() == 0);
            assertTrue(employee1.getCostCenter() == null);
            assertTrue(employee2.getCostCenter() == null);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test case: MotorVehicle.driver
     * <p>
     * Relationship mapping: ToOneFK, FetchType: lazy, owning side: left, cacheable: right
     */
    @Test
    @Bugzilla(bugid=309681)
    public void testMotorVehicleEmployee() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();
        final boolean isLazyToOneEnabled = false;

        MotorVehicle motorVehicle = new MotorVehicle();
        int employeeId = 11;
        Employee employee = new Employee(employeeId, "first", "driver", null);
        motorVehicle.setDriver(employee);
        employee.setMotorVehicle(motorVehicle);
        try {
            env.beginTransaction(em);
            em.persist(motorVehicle);
            em.persist(employee);
            env.commitTransactionAndClear(em);
            Short motorVehicleId = motorVehicle.getId();

            em.find(MotorVehicle.class, motorVehicleId);
            if (isLazyToOneEnabled) {
                assertTrue(!cache.contains(Employee.class, employeeId));
                employee = em.find(Employee.class, employeeId);
                // assertTrue(employee instanceof LazilyLoadable); FIXME
                // assertTrue( ((LazilyLoadable) employee)._isPending() ); FIXME
            } else {
                assertTrue(cache.contains(Employee.class, employeeId));
            }

            env.beginTransaction(em);
            motorVehicle = em.find(MotorVehicle.class, motorVehicleId);
            employee = em.find(Employee.class, employeeId);
            assertTrue(employeeId == motorVehicle.getDriver().getId());
            assertTrue(motorVehicleId.equals(employee.getMotorVehicle().getId()));
            assertTrue(employee == motorVehicle.getDriver());
            motorVehicle.setDriver(null);
            employee.setMotorVehicle(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(Employee.class, employeeId));
            motorVehicle = em.find(MotorVehicle.class, motorVehicleId);
            employee = em.find(Employee.class, employeeId);
            assertTrue(motorVehicle.getDriver() == null);
            assertTrue(employee.getMotorVehicle() == null);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test case: Employee.cubicle
     * <p>
     * Relationship mapping: ToOneFK, FetchType: eager, owning side: right, cacheable: both
     */
    @Test
    @Bugzilla(bugid=309681)
    public void testCubicleEmployee() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();

        int employeeId = 21;
        Employee employee = new Employee(employeeId, "first", "last", null);
        CubiclePrimaryKeyClass cubicleId = new CubiclePrimaryKeyClass(1, 2);
        Cubicle cubicle = new Cubicle(cubicleId, "red", employee);
        employee.setCubicle(cubicle);
        try {
            env.beginTransaction(em);
            em.persist(employee);
            em.persist(cubicle);
            env.commitTransactionAndClear(em);

            em.find(Cubicle.class, cubicleId);
            assertTrue(cache.contains(Cubicle.class, cubicleId));
            assertTrue(cache.contains(Employee.class, employeeId));

            env.beginTransaction(em);
            cubicle = em.find(Cubicle.class, cubicleId);
            employee = em.find(Employee.class, employeeId);
            assertTrue("cubicle has wrong employee: " + cubicle.getEmployee().getId(), employeeId == cubicle.getEmployee()
                    .getId());
            assertTrue("employee has wrong cubicle: " + employee.getCubicle().getId(), cubicleId.equals(employee.getCubicle()
                    .getId()));
            cubicle.setEmployee(null);
            employee.setCubicle(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(Cubicle.class, cubicleId));
            assertTrue(!cache.contains(Employee.class, employeeId));
            cubicle = em.find(Cubicle.class, cubicleId);
            employee = em.find(Employee.class, employeeId);
            assertTrue(cubicle.getEmployee() == null);
            assertTrue(employee.getCubicle() == null);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test case: Bicycle.employees
     * <p>
     * Relationship mapping: ToManyJoinTable, FetchType: eager, owning side: left, cacheable: right
     */
    @Test
    @Bugzilla(bugid=309681)
    public void testBicycleEmployee() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();

        Bicycle bicycle = new Bicycle();
        int employeeId1 = 31;
        int employeeId2 = 32;
        Employee employee1 = new Employee(employeeId1, "good", "rider1", null);
        Employee employee2 = new Employee(employeeId2, "bad", "rider2", null);
        employee1.addBicycle(bicycle); // maintains also bicycle.riders relationship
        employee2.addBicycle(bicycle);
        try {
            env.beginTransaction(em);
            em.persist(bicycle);
            em.persist(employee1);
            em.persist(employee2);
            env.commitTransactionAndClear(em);
            Short bicycleId = bicycle.getId();

            em.find(Bicycle.class, bicycleId); // eager loading of Employees
            assertTrue(cache.contains(Employee.class, employeeId1));
            assertTrue(cache.contains(Employee.class, employeeId2));

            env.beginTransaction(em);
            bicycle = em.find(Bicycle.class, bicycleId);
            employee1 = em.find(Employee.class, employeeId1);
            employee2 = em.find(Employee.class, employeeId2);
            Collection<Employee> foundRiders = bicycle.getRiders();
            assertTrue(foundRiders != null);
            assertTrue("wrong number of riders: " + foundRiders.size(), foundRiders.size() == 2);
            Employee[] ridersArray = foundRiders.toArray(new Employee[2]);
            if (ridersArray[0].getId() == employeeId1) {
                assertTrue("wrong rider: " + ridersArray[1].getId(), ridersArray[1].getId() == employeeId2);
            } else {
                assertTrue("wrong rider: " + ridersArray[0].getId(), ridersArray[0].getId() == employeeId2);
                assertTrue("wrong rider: " + ridersArray[1].getId(), ridersArray[1].getId() == employeeId1);
            }
            Set<Bicycle> bicycles1 = employee1.getBicycles();
            Set<Bicycle> bicycles2 = employee2.getBicycles();
            assertTrue(bicycles1 != null);
            assertTrue(bicycles2 != null);
            assertTrue(bicycles1.size() == 1);
            assertTrue(bicycles2.size() == 1);
            assertTrue(bicycleId.equals(bicycles1.toArray(new Bicycle[1])[0].getId()));
            assertTrue(bicycleId.equals(bicycles2.toArray(new Bicycle[1])[0].getId()));
            bicycle.setRiders(null);
            employee1.setBicycles(null);
            employee2.setBicycles(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(Employee.class, employeeId1));
            assertTrue(!cache.contains(Employee.class, employeeId2));
            bicycle = em.find(Bicycle.class, bicycleId);
            employee1 = em.find(Employee.class, employeeId1);
            employee2 = em.find(Employee.class, employeeId2);
            assertTrue(bicycle.getRiders().size() == 0);
            assertTrue(employee1.getBicycles().size() == 0);
            assertTrue(employee2.getBicycles().size() == 0);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test case: Employee.projects
     * <p>
     * Relationship mapping: ToManyJoinTable, FetchType: lazy, owning side: left, cacheable: both
     */
    @SuppressWarnings("unchecked")
    @Test
    @Bugzilla(bugid=309681)
    public void testEmployeeProject() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();

        int employeeId = 41;
        Employee employee = new Employee(employeeId, "aaa", "member", null);
        Project project1 = new Project("evaluation");
        Project project2 = new Project("demotivation");
        project1.addEmployee(employee); // maintains also employee.projects relationship
        project2.addEmployee(employee);
        try {
            env.beginTransaction(em);
            em.persist(employee);
            em.persist(project1);
            em.persist(project2);
            env.commitTransactionAndClear(em);
            Integer projectId1 = project1.getId();
            Integer projectId2 = project2.getId();

            env.beginTransaction(em);
            employee = em.find(Employee.class, employeeId);
            assertTrue(cache.contains(Employee.class, employeeId));
            assertTrue(!cache.contains(Project.class, projectId1)); // lazy loading of projects
            assertTrue(!cache.contains(Project.class, projectId2));
            employee.getProjects().size();
            assertTrue(cache.contains(Project.class, projectId1));
            assertTrue(cache.contains(Project.class, projectId2));
            project1 = em.find(Project.class, projectId1);
            project2 = em.find(Project.class, projectId2);
            Set<Project> foundProjects = employee.getProjects();
            assertTrue(foundProjects != null);
            assertTrue("wrong number of projects: " + foundProjects.size(), foundProjects.size() == 2);
            Project[] projArray = foundProjects.toArray(new Project[2]);
            if (projArray[0].getId().equals(projectId1)) {
                assertTrue("wrong project: " + projArray[1].getId(), projArray[1].getId().equals(projectId2));
            } else {
                assertTrue("wrong project: " + projArray[0].getId(), projArray[0].getId().equals(projectId2));
                assertTrue("wrong project: " + projArray[1].getId(), projArray[1].getId().equals(projectId1));
            }
            Set<Employee> employees1 = project1.getEmployees();
            Set<Employee> employees2 = project2.getEmployees();
            assertTrue(employees1 != null);
            assertTrue(employees2 != null);
            assertTrue(employees1.size() == 1);
            assertTrue(employees2.size() == 1);
            assertTrue(employees1.toArray(new Employee[1])[0].getId() == employeeId);
            assertTrue(employees2.toArray(new Employee[1])[0].getId() == employeeId);
            employee.setProjects(null);
            project1.setEmployees(null);
            project2.setEmployees(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(Employee.class, employeeId));
            assertTrue(!cache.contains(Project.class, projectId1));
            assertTrue(!cache.contains(Project.class, projectId2));
            employee = em.find(Employee.class, employeeId);
            project1 = em.find(Project.class, projectId1);
            project2 = em.find(Project.class, projectId2);
            assertTrue(employee.getProjects().size() == 0);
            assertTrue(project1.getEmployees().size() == 0);
            assertTrue(project2.getEmployees().size() == 0);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test case: TravelProfile.vehicles
     * <p>
     * Relationship mapping: ToManyJoinTable, FetchType: lazy, owning side: right, cacheable: right
     */
    @SuppressWarnings("unchecked")
    @Test
    @ToBeInvestigated
    public void testTravelProfileVehicle() { // TODO remove
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        final Cache cache = em.getEntityManagerFactory().getCache();

        byte[] travelProfileId = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
        TravelProfile travelProfile = new TravelProfile(travelProfileId, true, "neverComeBack");
        Vehicle vehicle1 = new Vehicle();
        Vehicle vehicle2 = new Vehicle();
        vehicle1.addProfile(travelProfile); // maintains also travelProfile.vehicles relationship
        vehicle2.addProfile(travelProfile);
        try {
            env.beginTransaction(em);
            em.persist(travelProfile);
            em.persist(vehicle1);
            em.persist(vehicle2);
            env.commitTransactionAndClear(em);
            Short vehicleId1 = vehicle1.getId();
            Short vehicleId2 = vehicle2.getId();

            env.beginTransaction(em);
            travelProfile = em.find(TravelProfile.class, travelProfileId);
            assertTrue(!cache.contains(Vehicle.class, vehicleId1)); // lazy loading of vehicles
            assertTrue(!cache.contains(Vehicle.class, vehicleId2));
            travelProfile.getVehicles().size();
            assertTrue(cache.contains(Vehicle.class, vehicleId1));
            assertTrue(cache.contains(Vehicle.class, vehicleId2));
            vehicle1 = em.find(Vehicle.class, vehicleId1);
            vehicle2 = em.find(Vehicle.class, vehicleId2);
            Set<Vehicle> foundVehicles = travelProfile.getVehicles();
            assertTrue(foundVehicles != null);
            assertTrue("wrong number of vehicles: " + foundVehicles.size(), foundVehicles.size() == 2);
            Vehicle[] vehicleArray = foundVehicles.toArray(new Vehicle[2]);
            if (vehicleArray[0].getId().equals(vehicleId1)) {
                assertTrue("wrong vehicle: " + vehicleArray[1].getId(), vehicleArray[1].getId().equals(vehicleId2));
            } else {
                assertTrue("wrong vehicle: " + vehicleArray[0].getId(), vehicleArray[0].getId().equals(vehicleId2));
                assertTrue("wrong vehicle: " + vehicleArray[1].getId(), vehicleArray[1].getId().equals(vehicleId1));
            }
            Set<TravelProfile> travelProfiles1 = vehicle1.getProfiles();
            Set<TravelProfile> travelProfiles2 = vehicle2.getProfiles();
            assertTrue(travelProfiles1 != null);
            assertTrue(travelProfiles2 != null);
            assertTrue(travelProfiles1.size() == 1);
            assertTrue(travelProfiles2.size() == 1);
            assertTrue(Arrays.equals(travelProfiles1.toArray(new TravelProfile[1])[0].getGuid(), travelProfileId));
            assertTrue(Arrays.equals(travelProfiles2.toArray(new TravelProfile[1])[0].getGuid(), travelProfileId));
            travelProfile.setVehicles(null);
            vehicle1.setProfiles(null);
            vehicle2.setProfiles(null);
            env.commitTransactionAndClear(em);

            assertTrue(!cache.contains(Vehicle.class, vehicleId1));
            assertTrue(!cache.contains(Vehicle.class, vehicleId2));
            travelProfile = em.find(TravelProfile.class, travelProfileId);
            vehicle1 = em.find(Vehicle.class, vehicleId1);
            vehicle2 = em.find(Vehicle.class, vehicleId2);
            assertTrue(travelProfile.getVehicles().size() == 0);
            assertTrue(vehicle1.getProfiles().size() == 0);
            assertTrue(vehicle2.getProfiles().size() == 0);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    /**
     * just for the case that all other methods are skipped 
     */
    public void dummyTestMethod() {
        return;
    }

}
