/*
 * Copyright (c) 2013, 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
package org.eclipse.persistence.testing.tests.jpa.inheritance;

import java.util.HashMap;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.persistence.config.PersistenceUnitProperties;

public class TablePerClassInheritanceDDLTest extends TablePerClassInheritanceJUnitTest {
    static EntityManagerFactory factory;

    public TablePerClassInheritanceDDLTest() {
        super();
    }

    public TablePerClassInheritanceDDLTest(String name) {
        super(name);
    }

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("TablePerClassInheritanceDDLTest");
        suite.addTest(new TablePerClassInheritanceDDLTest("testSetup"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testCreateAssassinWithGun"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateAssassinWithGun"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateGunToAssassin"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testAddDirectElimination"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateDirectElimination"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testAddIndirectElimination"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateIndirectElimination"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateAssassinWithBombAndEliminations"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testNamedQueryFindAllWeapons"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testNamedQueryFindAllWeaponsWhereDescriptionContainsSniper"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testBatchFindAllWeapons"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testCreateNewSocialClubsWithMembers"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateSocialClub1Members"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateSocialClub2Members"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testValidateSocialClub3Members"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testAssassinOptimisticLocking"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testSpecialAssassinOptimisticLocking"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testAssassinOptimisticLockingUsingEntityManagerAPI"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testGunOptimisticLocking"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testUpdateAllQuery"));
        suite.addTest(new TablePerClassInheritanceDDLTest("testTeardown"));
        return suite;
    }

    /**
     * DDL should be generated when creating factory.
     */
    @Override
    public void testSetup() {
        clearCache();
        clearServerSessionCache();
        createEntityManager().close();
        // Only test DDL on Oracle.
        if (!getServerSession().getPlatform().isOracle()) {
            super.testSetup();
        }
    }

    /**
     * DDL should be generated when creating factory.
     */
    public void testTeardown() {
        if (factory != null) {
            factory.close();
            factory = null;
        }
    }

    /**
     * Use a custom factory to generate DDL.
     */
    @Override
    public EntityManagerFactory getEntityManagerFactory() {
        if (factory == null) {
            // Only test DDL on Oracle, otherwise will have constraint issues.
            if (!getServerSession().getPlatform().isOracle()) {
                factory = Persistence.createEntityManagerFactory(getPersistenceUnitName());
                return factory;
            }
            // Ensure real one inits first.
            super.createEntityManager().close();

            Map properties = new HashMap(getPersistenceProperties());
            properties.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.DROP_AND_CREATE);
            properties.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION);
            properties.put(PersistenceUnitProperties.SESSION_NAME, "TablePerClassInheritanceDDLTest");
            factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
        }
        return factory;
    }

    /**
     * Use a custom factory to generate DDL.
     */
    @Override
    public EntityManager createEntityManager() {
        return getEntityManagerFactory().createEntityManager();
    }
}

