/*
 * 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.query;

import java.sql.Date;
import java.util.Calendar;

import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TemporalType;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.EmploymentPeriod;
import org.junit.Test;

public class TestQueryAPI extends QueryTest {

    private static final String queryStringOrderedParam = "SELECT e FROM Employee e WHERE e.firstname = ?1";
    private static final String queryStringNamedParam = "SELECT e FROM Employee e WHERE e.firstname = :firstname";

    private static final String queryStringOrderedCalendarParam = "SELECT btfa FROM BasicTypesFieldAccess btfa WHERE btfa.utilCalendar = ?1";
    private static final String queryStringNamedCalendarParam = "SELECT btfa FROM BasicTypesFieldAccess btfa WHERE btfa.utilCalendar = :parameter1";
    private static final String queryStringOrderedDateParam = "SELECT btfa FROM BasicTypesFieldAccess btfa WHERE btfa.utilDate = ?1";
    private static final String queryStringNamedDateParam = "SELECT btfa FROM BasicTypesFieldAccess btfa WHERE btfa.utilDate = :parameter1";

    @Override
    protected void setup() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            Employee emp = new Employee();
            EmploymentPeriod empPeriod = new EmploymentPeriod();
            empPeriod.setStartDate(new Date(System.currentTimeMillis() - Integer.MAX_VALUE));
            empPeriod.setEndDate(new Date(System.currentTimeMillis()));
            emp.setFirstName("Hans");
            emp.setLastName("Wurst");
            emp.setEmploymentPeriod(empPeriod);
            env.beginTransaction(em);
            em.persist(emp);
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    private void assertOrderedParameterValid(final Query query, int number, final Object value) {
        query.setParameter(number, value);
    }

    private void assertOrderedParameterInvalid(final Query query, int number, final Object value) {
        boolean passed = false;
        try {
            query.setParameter(number, value);
        } catch (IllegalArgumentException e) {
            passed = true;
        }
        verify(passed, ("missing IllegalArgumentException"));
    }

    private void assertNamedParameterValid(final Query query, final String name, final Object value) {
        query.setParameter(name, value);
    }

    private void assertNamedParameterInvalid(final Query query, final String name, final Object value) {
        boolean passed = false;
        try {
            query.setParameter(name, value);
        } catch (IllegalArgumentException e) {
            passed = true;
        }
        verify(passed, "missing IllegalArgumentException");
    }

    private void assertValidQuery(final EntityManager em, final String query) {
        em.createQuery(query);
    }

    private void assertInvalidQuery(final EntityManager em, final String query) {
        boolean passed = false;
        try {
            em.createQuery(query);
        } catch (IllegalArgumentException iaex) {
            passed = true;
        }
        verify(passed, "missing IllegalArgumentException");
    }

    @Test
    public void testQueryCreation() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            assertValidQuery(em, "SELECT e FROM Employee e");
            assertInvalidQuery(em, "SELECT BLAAfjdslkaf fasflkfj weoi jasdf");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testParameterSetting() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();

        try {
            // test valid ordered param
            Query q1 = em.createQuery(queryStringOrderedParam);
            assertOrderedParameterValid(q1, 1, "hugo");

            // test valid named param
            Query q2 = em.createQuery(queryStringNamedParam);
            assertNamedParameterValid(q2, "firstname", "elmar");

            // test invalid typed ordered param
            Query q3 = em.createQuery(queryStringOrderedParam);
            assertOrderedParameterInvalid(q3, 1, 2);

            // test invalid typed named param
            Query q4 = em.createQuery(queryStringNamedParam);
            assertNamedParameterInvalid(q4, "firstname", 3);

            // test invalid named ordered param
            Query q5 = em.createQuery(queryStringOrderedParam);
            assertOrderedParameterInvalid(q5, 2, "wursti");

            // test invalid named named param
            Query q6 = em.createQuery(queryStringNamedParam);
            assertNamedParameterInvalid(q6, "lastname", "olga");

            // test calendar named param
            Query q7 = em.createQuery(queryStringNamedCalendarParam);
            assertParameterValid(q7, new InputParameterHolder("parameter1", Calendar.getInstance(), TemporalType.TIMESTAMP));

            // test calendar ordered param
            Query q8 = em.createQuery(queryStringOrderedCalendarParam);
            assertParameterValid(q8, new InputParameterHolder(1, Calendar.getInstance(), TemporalType.TIMESTAMP));

            // test calendar ordered param
            @SuppressWarnings("unused")
            Query q9 = em.createQuery(queryStringOrderedDateParam);
            assertParameterValid(q8, new InputParameterHolder(1, new java.util.Date(System.currentTimeMillis()),
                    TemporalType.TIMESTAMP));

            // test calendar ordered param
            @SuppressWarnings("unused")
            Query q10 = em.createQuery(queryStringNamedDateParam);
            assertParameterValid(q8, new InputParameterHolder(1, new java.util.Date(System.currentTimeMillis()),
                    TemporalType.TIMESTAMP));

        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @ToBeInvestigated
    public void testTemporalParameterSettingInvalid() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();

        try {
            // test calendar named param
            Query q7 = em.createQuery(queryStringNamedCalendarParam);
            assertParameterInvalid(q7, new InputParameterHolder("parameter1", Calendar.getInstance()));

            // test calendar ordered param
            Query q8 = em.createQuery(queryStringOrderedCalendarParam);
            assertParameterInvalid(q8, new InputParameterHolder(1, Calendar.getInstance()));

            // test calendar ordered param
            Query q9 = em.createQuery(queryStringOrderedDateParam);
            assertParameterInvalid(q9, new InputParameterHolder(1, new java.util.Date(System.currentTimeMillis())));

            // test calendar ordered param
            Query q10 = em.createQuery(queryStringNamedDateParam);
            assertParameterInvalid(q10, new InputParameterHolder(1, new java.util.Date(System.currentTimeMillis())));

        } finally {
            closeEntityManager(em);
        }
    }

}
