/*
 * 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.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class TestUpdate extends JPA1Base {

    @Test
    public void testUpdateOfComposoiteKey() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            CubiclePrimaryKeyClass cubKey = new CubiclePrimaryKeyClass(40, 41);
            Cubicle cub = new Cubicle(cubKey, "green", null /* employee */
            );
            env.beginTransaction(em);
            em.persist(cub);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            cub = em.find(Cubicle.class, cubKey);
            cub.setColor("blue");
            env.commitTransactionAndClear(em);
            cub = em.find(Cubicle.class, cubKey);
            verify(cub != null, "cubicle null");
            verify(cub.getColor().equals("blue"), "wrong color");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testUpdateRelationWithCompositeKey() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        env.evictAll(em);
        try {
            Employee emp = new Employee(17, "first", "last", null /* department */
            );
            CubiclePrimaryKeyClass key1 = new CubiclePrimaryKeyClass(98, 99);
            CubiclePrimaryKeyClass key2 = new CubiclePrimaryKeyClass(5, 6);
            Cubicle cub1 = new Cubicle(key1, "orange", emp);
            env.beginTransaction(em);
            emp.setCubicle(cub1);
            em.persist(emp);
            em.persist(cub1);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp = em.find(Employee.class, 17);
            Cubicle cub2 = new Cubicle(key2, "dusky pink", emp);
            emp.setCubicle(cub2);
            em.persist(cub2);
            env.commitTransactionAndClear(em);
            emp = em.find(Employee.class, 17);
            verify(emp != null, "employee lost");
            verify(emp.getCubicle() != null, "cubicle lost");
            CubiclePrimaryKeyClass key = emp.getCubicle().getId();
            verify(key.equals(key2), "wrong cubicle");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testUpdatePrimaryKey() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Department dep = new Department(1, "JST");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransaction(em);
            em.clear();
            env.beginTransaction(em);
            dep = em.find(Department.class, dep.getId());
            dep.setId(99);
            try {
                env.commitTransaction(em);
                flop("exception not thrown as expected");
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
            }
        } finally {
            closeEntityManager(em);
        }
    }
}
