/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. 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:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import jakarta.persistence.EntityManager;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
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.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.island.Island;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class TestFind extends JPA1Base {

    private final Department _dep = new Department(1, "eins");
    private final Employee _emp = new Employee(7, "first", "last", _dep);
    private final Cubicle _cub = new Cubicle(Integer.valueOf(1), Integer.valueOf(2), "yellow", _emp);

    @Override
    public void setup() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            em.persist(_dep);
            em.persist(_emp);
            em.persist(_cub);
            em.flush();
            env.commitTransactionAndClear(em);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPositivTx() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, Integer.valueOf(7));
            verify(em.contains(emp), "Object not loaded");
            verify(emp.getId() == 7, "wrong id");
            verify(emp.getDepartment().getName().equals("eins"), "wrong department");
            emp = em.find(Employee.class, Integer.valueOf(7));
            verify(emp.getId() == 7, "wrong id");
            Department dep = em.find(Department.class, Integer.valueOf(1));
            verify(em.contains(dep), "Object not loaded");
            verify(dep.getId() == 1, "wrong id");
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPositivNonTx() {
        final EntityManager em = getEnvironment().getEntityManager();
        try {
            Employee emp = em.find(Employee.class, Integer.valueOf(7));
            verify(emp.getId() == 7, "wrong id");
            verify(emp.getDepartment().getName().equals("eins"), "wrong department");
            emp = em.find(Employee.class, Integer.valueOf(7));
            verify(emp.getId() == 7, "wrong id");
            Department dep = em.find(Department.class, Integer.valueOf(1));
            verify(dep.getId() == 1, "wrong id");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testNegativ() {
        final EntityManager em = getEnvironment().getEntityManager();
        try {
            Object result = em.find(Employee.class, Integer.valueOf(17 + 12345));
            verify(result == null, "found something");
        } finally {
            closeEntityManager(em);
        }
    }

    /*
     * IllegalArgumentException, if the first argument does not denote an entity type or the second argument is not a valid type
     * for that entity's primary key.
     */
    @Test
    public void testIllegalArguments() {
        final EntityManager em = getEnvironment().getEntityManager();
        try {
            try {
                em.find(String.class, Integer.valueOf(17 + 4));
                flop("no IllegalArgumentException thrown");
            } catch (IllegalArgumentException ex) {
                verify(true, "");
            }
            try {
                em.find(Employee.class, "illegal key");
                flop("no IllegalArgumentException thrown");
            } catch (IllegalArgumentException ex) {
                verify(true, "");
            }
            try {
                em.find(Employee.class, null);
                flop("no IllegalArgumentException thrown");
            } catch (IllegalArgumentException ex) {
                verify(true, "");
            }
            try {
                em.find(null, "illegal key");
                flop("no IllegalArgumentException thrown");
            } catch (IllegalArgumentException ex) {
                verify(true, "");
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testFindWithCompositeKey() {
        final EntityManager em = getEnvironment().getEntityManager();
        try {
            Integer one = Integer.valueOf(1);
            Integer two = Integer.valueOf(2);
            CubiclePrimaryKeyClass cubKey = new CubiclePrimaryKeyClass(one, two);
            Cubicle cub = em.find(Cubicle.class, cubKey);
            verify(cub.getFloor().equals(one) && cub.getPlace().equals(two), "wrong cubicle");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testFindRemoved() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Island island = new Island();
            em.persist(island);
            env.commitTransactionAndClear(em);
            Integer islandId = Integer.valueOf(island.getId());
            env.beginTransaction(em);
            island = em.find(Island.class, islandId);
            em.remove(island);
            verify(em.find(Island.class, islandId) == null, "entity in state FOR_DELETE but found by find");
            env.rollbackTransactionAndClear(em);
            env.beginTransaction(em);
            island = em.find(Island.class, islandId);
            em.remove(island);
            em.flush();
            verify(em.find(Island.class, islandId) == null, "entity in state DELETE_EXECUTED but found by find");
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }
}
