/*
 * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. 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:
//     09/06/2019 - Will Dazey
//       - 55054 : Add Oracle support for named parameters with stored procedures
package org.eclipse.persistence.jpa.test.storedproc;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.ParameterMode;
import jakarta.persistence.StoredProcedureQuery;

import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.jpa.test.framework.DDLGen;
import org.eclipse.persistence.jpa.test.framework.Emf;
import org.eclipse.persistence.jpa.test.framework.EmfRunner;
import org.eclipse.persistence.jpa.test.framework.Property;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
import org.eclipse.persistence.tools.schemaframework.StoredProcedureDefinition;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EmfRunner.class)
public class TestStoredProcedures {

    @Emf(name = "storedProcedureEmf", createTables = DDLGen.DROP_CREATE,
            //This property ('enableNamedParameterMarkers') is needed for DB2Z named parameters
            properties = { @Property(name = "eclipselink.jdbc.property.enableNamedParameterMarkers", value = "true") } )
    private EntityManagerFactory storedProcedureEmf;

    @Before
    public void setup() {
        //Attempt to setup the stored procedure for testing.
        Assume.assumeTrue("Platform " + getPlatform(storedProcedureEmf) + " is not supported for this test", 
                createSimpleStoredProcedure(storedProcedureEmf));
    }

    /**
     * Tests stored procedure using indexed parameters
     */
    @Test
    public void testStoredProcedure_SetOrdered_IndexParameters() {
        EntityManager em = storedProcedureEmf.createEntityManager();
        try {
            StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("simple_order_procedure");
            storedProcedure.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(3, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(4, String.class, ParameterMode.OUT);

            storedProcedure.setParameter(1, "One");
            storedProcedure.setParameter(2, "Two");
            storedProcedure.setParameter(3, "Three");

            storedProcedure.execute();

            String returnValue =  (String) storedProcedure.getOutputParameterValue(4);
            Assert.assertEquals("One: One Two: Two Three: Three", returnValue);
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if(em.isOpen()) {
                em.close();
            }
        }
    }

    /**
     * Tests stored procedure using indexed parameters, but alter the order to make sure the result doesn't change.
     */
    @Test
    public void testStoredProcedure_SetUnordered_IndexParameters() {
        EntityManager em = storedProcedureEmf.createEntityManager();
        try {
            StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("simple_order_procedure");
            storedProcedure.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(3, String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter(4, String.class, ParameterMode.OUT);

            storedProcedure.setParameter(2, "Two");
            storedProcedure.setParameter(1, "One");
            storedProcedure.setParameter(3, "Three");

            storedProcedure.execute();

            String returnValue =  (String) storedProcedure.getOutputParameterValue(4);
            Assert.assertEquals("One: One Two: Two Three: Three", returnValue);
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if(em.isOpen()) {
                em.close();
            }
        }
    }

    /**
     * Tests stored procedure using named parameters
     */
    @Test
    public void testStoredProcedure_SetOrdered_NamedParameters() {
        EntityManager em = storedProcedureEmf.createEntityManager();
        try {
            StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("simple_order_procedure");
            storedProcedure.registerStoredProcedureParameter("in_param_one", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("in_param_two", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("in_param_three", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("out_param_one", String.class, ParameterMode.OUT);

            storedProcedure.setParameter("in_param_one", "One");
            storedProcedure.setParameter("in_param_two", "Two");
            storedProcedure.setParameter("in_param_three", "Three");

            storedProcedure.execute();

            String returnValue =  (String) storedProcedure.getOutputParameterValue("out_param_one");
            Assert.assertEquals("One: One Two: Two Three: Three", returnValue);
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if(em.isOpen()) {
                em.close();
            }
        }
    }

    /**
     * Tests stored procedure using named parameters, but alter the order to make sure the result doesn't change.
     */
    @Test
    public void testStoredProcedure_SetUnordered_NamedParameters() {
        EntityManager em = storedProcedureEmf.createEntityManager();
        try {
            StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("simple_order_procedure");
            storedProcedure.registerStoredProcedureParameter("in_param_one", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("in_param_two", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("in_param_three", String.class, ParameterMode.IN);
            storedProcedure.registerStoredProcedureParameter("out_param_one", String.class, ParameterMode.OUT);

            storedProcedure.setParameter("in_param_three", "Three");
            storedProcedure.setParameter("in_param_two", "Two");
            storedProcedure.setParameter("in_param_one", "One");

            storedProcedure.execute();

            String returnValue =  (String) storedProcedure.getOutputParameterValue("out_param_one");
            Assert.assertEquals("One: One Two: Two Three: Three", returnValue);
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if(em.isOpen()) {
                em.close();
            }
        }
    }

    /**
     * Creates a simple stored procedure for the given EntityManagerFactory
     * @return boolean indicating if storedProcedure was created
     */
    private static boolean createSimpleStoredProcedure(EntityManagerFactory emf) {
        //Setup a stored procedure
        EntityManager em = emf.createEntityManager();
        try {
            StoredProcedureDefinition proc = new StoredProcedureDefinition();
            proc.setName("simple_order_procedure");

            proc.addArgument("in_param_one", String.class, 10);
            proc.addArgument("in_param_two", String.class, 10);
            proc.addArgument("in_param_three", String.class, 10);
            proc.addOutputArgument("out_param_one", String.class, 30);

            DatabaseSession dbs = ((EntityManagerImpl)em).getDatabaseSession();
            SchemaManager manager = new SchemaManager(dbs);
            Platform platform = dbs.getDatasourcePlatform();

            //Add more platform specific diction to support more platforms
            if(platform.isMySQL()) {
                proc.addStatement("SET out_param_one = CONCAT('One: ',in_param_one,' Two: ',in_param_two,' Three: ',in_param_three)");
            } else if(platform.isOracle()) {
                proc.addStatement("out_param_one := 'One: ' || in_param_one || ' Two: ' || in_param_two || ' Three: ' || in_param_three");
            } else if (platform.isDB2() || platform.isDB2Z()) {
                proc.addStatement("SET out_param_one = 'One: ' || in_param_one || ' Two: ' || in_param_two || ' Three: ' || in_param_three");
            } else {
                return false;
            }

            try {
                manager.dropObject(proc);
            } catch(Exception e) {
                //Ignore any drop exceptions since the procedure may not exist yet
            }

            manager.createObject(proc);
            return true;
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if(em.isOpen()) {
                em.close();
            }
        }
    }

    private static DatabasePlatform getPlatform(EntityManagerFactory emf) {
        return ((EntityManagerFactoryImpl)emf).getServerSession().getPlatform();
    }
}
