/*
 * Copyright (c) 2012, 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:
//     11/19/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
//     11/22/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (index metadata support)
//     12/07/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
//     01/23/2013-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     04/12/2013-2.5 Guy Pelletier
//       - 405640: JPA 2.1 schema generation drop operation fails to include dropping defaulted fk constraints.
package org.eclipse.persistence.testing.tests.jpa22.advanced;

import java.util.Date;
import java.util.Map;

import jakarta.persistence.EntityManager;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.DirectMapMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;

import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;

import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Coach;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Organizer;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Race;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Responsibility;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Runner;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.RunnerInfo;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.RunnerStatus;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Shoe;
import org.eclipse.persistence.testing.models.jpa22.advanced.ddl.Sprinter;

import org.eclipse.persistence.testing.models.jpa22.advanced.enums.Health;
import org.eclipse.persistence.testing.models.jpa22.advanced.enums.Level;
import org.eclipse.persistence.testing.models.jpa22.advanced.enums.RunningStatus;

import org.eclipse.persistence.tools.schemaframework.ForeignKeyConstraint;

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

public class ForeignKeyTestSuite extends JUnitTestCase {
    public ForeignKeyTestSuite() {}

    public ForeignKeyTestSuite(String name) {
        super(name);
        setPuName("MulitPU-2");
    }

    protected void assertForeignKeyConstraint(String name, String definition, DatabaseTable table) {
        assertTrue("No foreign key constraints were found on table [" + table.getName()+ "]", table.hasForeignKeyConstraints());
        ForeignKeyConstraint constraint = table.getForeignKeyConstraint(name);
        assertNotNull("The foreign key constraint named [" + name + "] was not found on table [" + table.getName() + "]", constraint);
        assertFalse("The foreign key definition for the constraint named [" + name + "] on table [" + table + "] was null.", constraint.getForeignKeyDefinition() == null);
        assertTrue("The foreign key definition for the constraint named [" + name + "] on table [" + table + "] was set as [" + constraint.getForeignKeyDefinition() + " ], but was expecting [" + definition + " ]", constraint.getForeignKeyDefinition().equals(definition));
    }

    /**
     * Return the the persistence unit name for this test suite.
     */
    @Override
    public String getPersistenceUnitName() {
        return "MulitPU-2";
    }

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("ForeignKeyTestSuite");

        suite.addTest(new ForeignKeyTestSuite("testInheritancePrimaryKeyForeignKey"));
        suite.addTest(new ForeignKeyTestSuite("testCollectionTableForeignKey"));
        suite.addTest(new ForeignKeyTestSuite("testJoinTableForeignKeys"));
        suite.addTest(new ForeignKeyTestSuite("testMapKeyForeignKey"));
        suite.addTest(new ForeignKeyTestSuite("testManyToOneForeignKey"));
        suite.addTest(new ForeignKeyTestSuite("testElementCollectionForeignKeys"));

        suite.addTest(new ForeignKeyTestSuite("testReadAndWriteDDLObjects"));


        return suite;
    }

    /**
     * Tests an inheritance primary key foreign key setting.
     */
    public void testInheritancePrimaryKeyForeignKey() {
        ClassDescriptor sprinterDescriptor = getPersistenceUnitServerSession().getDescriptor(Sprinter.class);
        DatabaseTable table = sprinterDescriptor.getTable("JPA22_DDL_SPRINTER");

        assertForeignKeyConstraint("Sprinter_Foreign_Key", "FOREIGN KEY (SPRINTER_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);
    }

    /**
     * Tests a collection table foreign key setting.
     */
    public void testCollectionTableForeignKey() {
        ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
        DirectCollectionMapping mapping = (DirectCollectionMapping) runnerDescriptor.getMappingForAttributeName("personalBests");
        DatabaseTable table = mapping.getReferenceTable();

        assertForeignKeyConstraint("Runner_PBS_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);
    }

    /**
     * Tests a join table foreign key settings.
     */
    public void testJoinTableForeignKeys() {
        ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
        ManyToManyMapping mapping = (ManyToManyMapping) runnerDescriptor.getMappingForAttributeName("races");
        DatabaseTable table = mapping.getRelationTable();

        assertForeignKeyConstraint("Runners_Races_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);
        assertForeignKeyConstraint("Runners_Races_Inverse_Foreign_Key", "FOREIGN KEY (RACE_ID) REFERENCES JPA22_DDL_RACE (ID)", table);
    }

    /**
     * Tests a map key foreign key setting.
     */
    public void testMapKeyForeignKey() {
        ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
        OneToManyMapping mapping = (OneToManyMapping) runnerDescriptor.getMappingForAttributeName("shoes");
        OneToOneMapping keyMapping = (OneToOneMapping) ((MappedKeyMapContainerPolicy) mapping.getContainerPolicy()).getKeyMapping();
        DatabaseTable table = keyMapping.getForeignKeyFields().get(0).getTable();

        assertForeignKeyConstraint("Runner_ShoeTag_Foreign_Key", "FOREIGN KEY (TAG_ID) REFERENCES JPA22_DDL_SHOE_TAG (ID)", table);
    }

    /**
     * Tests a many to one foreign key setting.
     */
    public void testManyToOneForeignKey() {
        ClassDescriptor shoeDescriptor = getPersistenceUnitServerSession().getDescriptor(Shoe.class);
        OneToOneMapping mapping = (OneToOneMapping) shoeDescriptor.getMappingForAttributeName("runner");
        DatabaseTable table = mapping.getForeignKeyFields().get(0).getTable();

        assertForeignKeyConstraint("Shoes_Runner_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);

        ClassDescriptor organizerDescriptor = getPersistenceUnitServerSession().getDescriptor(Organizer.class);
        mapping = (OneToOneMapping) organizerDescriptor.getMappingForAttributeName("race");
        table = mapping.getForeignKeyFields().get(0).getTable();

        assertForeignKeyConstraint("Organizer_Race_Foreign_Key", "FOREIGN KEY (RACE_ID) REFERENCES JPA22_DDL_RACE (ID)", table);
    }

    /**
     * Tests an element collection foreign key settings.
     */
    public void testElementCollectionForeignKeys() {
        ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
        DirectMapMapping mapping = (DirectMapMapping) runnerDescriptor.getMappingForAttributeName("endorsements");
        OneToOneMapping keyMapping = (OneToOneMapping) ((MappedKeyMapContainerPolicy) mapping.getContainerPolicy()).getKeyMapping();
        DatabaseTable table = mapping.getReferenceTable();

        assertForeignKeyConstraint("Endorsements_Foreign_Key", "FOREIGN KEY (ATHLETE_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);

        table = keyMapping.getForeignKeyFields().get(0).getTable();

        assertForeignKeyConstraint("Endorsements_Key_Foreign_Key", "FOREIGN KEY (ENDORSER_ID) REFERENCES JPA_DDL_ENDORSER (ID)", table);

        mapping = (DirectMapMapping) runnerDescriptor.getMappingForAttributeName("accomplishments");
        table = mapping.getReferenceTable();

        assertForeignKeyConstraint("Accomplistments_Foreign_Key", "FOREIGN KEY (ATHLETE_ID) REFERENCES JPA22_DDL_RUNNER (ID)", table);
    }

    /**
     * Test copied from Converter test suite. Will write and read the objects
     * back and at the same time test their converters as well.
     */
    public void testReadAndWriteDDLObjects() {
        EntityManager em = createEntityManager();

        try {
            beginTransaction(em);

            Runner runner = new Runner();
            runner.setAge(53);
            runner.setIsFemale();
            runner.setFirstName("Doris");
            runner.setLastName("Day");
            runner.addPersonalBest("10 KM", "47:34");
            runner.addPersonalBest("5", "26:41");
            runner.addAccomplishment("Ran 100KM without stopping", new Date(System.currentTimeMillis()));
            RunnerInfo runnerInfo = new RunnerInfo();
            runnerInfo.setHealth(Health.H);
            runnerInfo.setLevel(Level.A);
            RunnerStatus runnerStatus = new RunnerStatus();
            runnerStatus.setRunningStatus(RunningStatus.D);
            runnerInfo.setStatus(runnerStatus);
            runner.setInfo(runnerInfo);

            Coach coach = new Coach();
            runner.addCoach(coach);

            Race race = new Race();
            race.setName("The Ultimate Marathon");
            race.addRunner(runner);

            Organizer organizer = new Organizer();
            organizer.setName("Joe Organ");
            organizer.setRace(race);

            Responsibility responsibility = new Responsibility();
            responsibility.setUniqueIdentifier(System.currentTimeMillis());
            responsibility.setDescription("Raise funds");

            race.addOrganizer(organizer, responsibility);

            em.persist(race);
            em.persist(organizer);
            em.persist(runner);
            em.persist(coach);
            commitTransaction(em);

            // Clear the cache
            em.clear();
            clearCache();

            Runner runnerRefreshed = em.find(Runner.class, runner.getId());
            assertTrue("The age conversion did not work.", runnerRefreshed.getAge() == 52);
            assertTrue("The embeddable health conversion did not work.", runnerRefreshed.getInfo().getHealth().equals(Health.HEALTHY));
            assertTrue("The embeddable level conversion did not work.", runnerRefreshed.getInfo().getLevel().equals(Level.AMATEUR));
            assertTrue("The nested embeddable running status conversion did not work.", runnerRefreshed.getInfo().getStatus().getRunningStatus().equals(RunningStatus.DOWN_TIME));
            assertTrue("The number of personal bests for this runner is incorrect.", runnerRefreshed.getPersonalBests().size() == 2);
            assertTrue("Distance (map key) conversion did not work.", runnerRefreshed.getPersonalBests().keySet().contains("10K"));
            assertTrue("Distance (map key) conversion did not work.", runnerRefreshed.getPersonalBests().keySet().contains("5K"));
            assertTrue("Time (map value) conversion did not work.", runnerRefreshed.getPersonalBests().values().contains("47:34.0"));
            assertTrue("Time (map value) conversion did not work.", runnerRefreshed.getPersonalBests().values().contains("26:41.0"));

            Race raceRefreshed = em.find(Race.class, race.getId());
            Map<Responsibility, Organizer> organizers = raceRefreshed.getOrganizers();
            assertFalse("No race organizers returned.", organizers.isEmpty());
            assertTrue("More than one race organizer returned.", organizers.size() == 1);

            Responsibility resp = organizers.keySet().iterator().next();
            assertTrue("Responsibility was not uppercased by the converter", resp.getDescription().equals("RAISE FUNDS"));

            for (String accomplishment : runnerRefreshed.getAccomplishments().keySet()) {
                assertTrue("Accomplishment (map key) conversion did not work.", accomplishment.endsWith("!!!"));
            }
        } catch (RuntimeException e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }

            throw e;
        } finally {
            closeEntityManager(em);
        }
    }
}
