/*
 * Copyright (c) 2018, 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
 */

/* $Id: //dev/eclipselink/jpa/eclipselink.jpa.wdf.test/src/org/eclipse/persistence/testing/tests/wdf/jpa1/generator/TestIdentity.java#2 $
 * Last changelist: $Change: 3861, 2015 0 $
 * Last changed at: $DateTime: 2009/09/23 09:51:44 $
 * Last changed by: $Author: d024108 $
 */
package org.eclipse.persistence.testing.tests.wdf.jpa1.generator;

import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.EntityManager;

import org.junit.Assert;

import org.eclipse.persistence.platform.database.OraclePlatform;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.Skip;
import org.eclipse.persistence.testing.models.wdf.jpa1.myst.Cave;
import org.eclipse.persistence.testing.models.wdf.jpa1.myst.Creature;
import org.eclipse.persistence.testing.models.wdf.jpa1.myst.MythicalCreature;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class TestIdentity extends JPA1Base {

    @Test
    @Skip(databases = OraclePlatform.class, databaseNames="org.eclipse.persistence.platform.database.MaxDBPlatform")
    public void testPersist() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            em.getTransaction().begin();
            Creature fluppi1 = new Creature("fluppi1");
            fluppi1.setColor("red");
            Creature fluppi2 = new Creature("fluppi2");
            fluppi2.setColor("blue");
            Set<Creature> creatureSet = new HashSet<Creature>();
            creatureSet.add(fluppi1);
            creatureSet.add(fluppi2);
            em.persist(fluppi1);
            em.persist(fluppi2);

            em.flush(); // added as suggested by Andrei

            Integer id1 = fluppi1.getId();
            Integer id2 = fluppi2.getId();
            Assert.assertNotNull("id1 null", id1);
            Assert.assertNotNull("id2 null", id2);

            Integer caveId = id1 + 7;
            Cave darkHole = new Cave(caveId);
            darkHole.setName("dark hole");
            darkHole.setCreatures(creatureSet);
            em.persist(darkHole);

            em.getTransaction().commit();

            Creature fluppi3 = em.find(Creature.class, id1);
            Assert.assertEquals("wrong object name", fluppi1.getName(), fluppi3.getName());
            Assert.assertEquals("wrong object color", fluppi1.getColor(), fluppi3.getColor());

            fluppi3 = em.find(Creature.class, id2);
            Assert.assertEquals("wrong object name", fluppi2.getName(), fluppi3.getName());
            Assert.assertEquals("wrong object color", fluppi2.getColor(), fluppi3.getColor());

            Cave referenceCave = em.find(Cave.class, caveId);
            Set<Creature> referenceSet = referenceCave.getCreatures();
            Assert.assertEquals("wrong set size", referenceSet.size(), 2);
            Assert.assertEquals("missing element", referenceSet.contains(fluppi1), true);
            Assert.assertEquals("missing element", referenceSet.contains(fluppi2), true);

        } finally {
            if (env.isTransactionActive(em)) {
            env.rollbackTransactionAndClear(em);
            }
        }
    }

    @Test
    @Skip(databases = OraclePlatform.class, databaseNames="org.eclipse.persistence.platform.database.MaxDBPlatform")
    public void testMerge() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            em.getTransaction().begin();
            Creature schnappi1 = new Creature("schnappi");
            schnappi1.setColor("green");
            schnappi1 = em.merge(schnappi1);

            em.flush(); // added as suggested by Andrei

            Integer id = schnappi1.getId();
            Assert.assertNotNull("id null", id);
            em.getTransaction().commit();

            Creature schnappi2 = em.find(Creature.class, id);
            Assert.assertEquals("wrong object name", schnappi1.getName(), schnappi2.getName());
            Assert.assertEquals("wrong object color", schnappi1.getColor(), schnappi2.getColor());
            em.merge(schnappi2);
            Assert.assertEquals("id change", schnappi1.getId(), schnappi2.getId());
        } finally {
            if (env.isTransactionActive(em)) {
                env.rollbackTransactionAndClear(em);
            }
        }
    }

    // @Test
    // public void testForeignKey() throws SQLException {
    // //TODO
    // if (true) {
    // return;
    // }
    // final EntityManager em = emf.createEntityManager();
    // try {
    // execute(dataSource, addFK);
    //
    // em.getTransaction().begin();
    // Creature creature = new Creature("Creature");
    // Weapon weapon = new Weapon(47);
    // creature.setWeapon(weapon);
    // em.persist(creature);
    // em.persist(weapon);
    // em.getTransaction().commit();
    // //SQLException -> PersistenceException->IllegalArgumentException
    // } finally {
    // if (em.getTransaction().isActive()) {
    // em.getTransaction().rollback();
    // }
    // em.close();
    // execute(dataSource, dropFK);
    // }
    // }

    @Test
    @Skip(databases = OraclePlatform.class, databaseNames="org.eclipse.persistence.platform.database.MaxDBPlatform")
    public void testJoinedSubclass() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            em.getTransaction().begin();
            MythicalCreature unicorn = new MythicalCreature("unicorn");
            unicorn.setStory("once upon a time");
            unicorn.setColor("white");
            em.persist(unicorn);

            em.flush(); // added as suggested by Andrei

            Integer id = unicorn.getId();
            em.getTransaction().commit();
            MythicalCreature duocorn = em.find(MythicalCreature.class, id);
            Assert.assertEquals("wrong object name", unicorn.getName(), duocorn.getName());
            Assert.assertEquals("wrong object color", unicorn.getColor(), duocorn.getColor());
            Assert.assertEquals("wrong object story", unicorn.getStory(), duocorn.getStory());

        } finally {
            if (env.isTransactionActive(em)) {
                env.rollbackTransactionAndClear(em);
            }
        }
    }

    // @Test
    // public void testUnsupported() {
    // boolean caught = false;
    // try {
    // final Map<String, Object> map = new HashMap<String, Object>();
    // // map.put(Constants.JDBC_DATASOURCE, dataSource); FIXME
    // emf = Persistence.createEntityManagerFactory("ems/ATSTestEM_Identity", map);
    // } catch (PersistenceException pe) {
    // caught = true;
    // } finally {
    // if (emf != null) {
    // emf.close();
    // emf = null;
    // }
    // Assert.assertTrue("missing PersistenceException", caught);
    // }
    // }
    //
    @Test
    @Skip(databases = OraclePlatform.class, databaseNames="org.eclipse.persistence.platform.database.MaxDBPlatform")
    public void testPersistNoTx() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Creature fluppi1 = new Creature("fluppi1");
            fluppi1.setColor("red");
                em.persist(fluppi1);
                env.beginTransaction(em);
                env.commitTransaction(em);
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            em.close();
        }
    }

}
