/*
 * Copyright (c) 2005, 2020 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.util.Calendar;
import java.util.Date;
import java.util.Set;

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

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;

public abstract class QueryTest extends JPA1Base {

    protected void assertInvalidQueryWithParameters(String queryString, Set<InputParameterHolder> parameters) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            executeQueryWithParameters(queryString, parameters, em);
            message = "Failed to detect invalid query:'" + queryString + "'";
        } catch (IllegalArgumentException IAex) {
            isPassed = true;
            message = IAex.getMessage();
        }
        verify(isPassed, message);
    }

    /**
     * @param queryString
     * @param parameters
     * @param em
     */
    private void executeQueryWithParameters(String queryString, Set<InputParameterHolder> parameters, EntityManager em) {
        Query query = em.createQuery(queryString);
        for (InputParameterHolder holder : parameters) {

            setParameterHolder(query, holder);
        }
    }

    /**
     * @param query
     * @param holder
     */
    private void setParameterHolder(Query query, InputParameterHolder holder) {
        if (holder.isTemporal()) {
            if (holder.getType() == ParameterType.POSITIONAL) {
                if (holder.getValue() instanceof Date) {
                    query.setParameter((Integer) holder.getIdentitfier(), (Date) holder.getValue(), holder.getTemporalType());
                } else if (holder.getValue() instanceof Calendar) {
                    query.setParameter((Integer) holder.getIdentitfier(), (Calendar) holder.getValue(), holder
                            .getTemporalType());
                }
            } else if (holder.getType() == ParameterType.NAMED) {
                if (holder.getValue() instanceof Date) {
                    query.setParameter((String) holder.getIdentitfier(), (Date) holder.getValue(), holder.getTemporalType());
                } else if (holder.getValue() instanceof Calendar) {
                    query
                            .setParameter((String) holder.getIdentitfier(), (Calendar) holder.getValue(), holder
                                    .getTemporalType());
                }
            }
        } else {
            if (holder.getType() == ParameterType.POSITIONAL) {
                query.setParameter((Integer) holder.getIdentitfier(), holder.getValue());
            } else if (holder.getType() == ParameterType.NAMED) {
                query.setParameter((String) holder.getIdentitfier(), holder.getValue());
            }
        }
    }

    protected void assertValidQueryWithParameters(String queryString, Set<InputParameterHolder> parameters) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            executeQueryWithParameters(queryString, parameters, em);
            message = "Test successfully passed.";
            isPassed = true;
        } catch (IllegalArgumentException IAex) {
            message = IAex.getMessage();
        }
        verify(isPassed, message);
    }

    protected void assertParameterValid(Query query, InputParameterHolder holder) {
        setParameterHolder(query, holder);
    }

    protected void assertParameterInvalid(Query query, InputParameterHolder holder) {
        boolean passed = false;
        try {
            setParameterHolder(query, holder);
        } catch (IllegalArgumentException e) {
            passed = true;
        }
        verify(passed, ("missing IllegalArgumentException"));
    }

    protected void assertValidUpdateExecution(String queryString) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            getEnvironment().beginTransaction(em);
            Query q = em.createQuery(queryString);
            q.executeUpdate();
            message = "Query '" + queryString + "' was successfully created.";
            isPassed = true;
            getEnvironment().commitTransactionAndClear(em);
        } catch (Exception ex) {
            getEnvironment().rollbackTransactionAndClear(em);
            message = ex.getMessage();
        }
        verify(isPassed, message);
    }

    protected void assertInvalidUpdateExecution(String queryString) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            getEnvironment().beginTransaction(em);
            Query q = em.createQuery(queryString);
            q.executeUpdate();
            message = "Failed to detect invalid query:'" + queryString + "'";
            getEnvironment().commitTransactionAndClear(em);
        } catch (Exception ex) {
            isPassed = true;
            message = ex.getMessage();
            getEnvironment().rollbackTransactionAndClear(em);
        }
        verify(isPassed, message);
    }

    protected void assertValidQuery(String queryString) {
        EntityManager em = getEnvironment().getEntityManager();
        try {
            em.createQuery(queryString);
        } catch (RuntimeException e) {
            throw new RuntimeException("An exception occurred while creating a query for String >>" + queryString + "<<", e);
        }
    }

    protected void assertInvalidQuery(String queryString) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            Query query = em.createQuery(queryString);
            try {
                query.getResultList();

                message = "Failed to detect invalid query:'" + queryString + "'";
            } catch (PersistenceException ex) {
                isPassed = true;
                message = ex.getMessage();
            } catch (DatabaseException ex) { // FIXME
                isPassed = true;
                message = ex.getMessage();
            }
        } catch (IllegalArgumentException IAex) {
            isPassed = true;
            message = IAex.getMessage();
        } catch (QueryException ex) { // FIXME
            isPassed = true;
            message = ex.getMessage();
        }
        verify(isPassed, message);
    }

    protected void assertInvalidQueryExecution(String queryString) {
        boolean isPassed = false;
        String message;
        EntityManager em = getEnvironment().getEntityManager();
        try {
            Query q = em.createQuery(queryString);
            q.getResultList();
            message = "Failed to detect invalid query:'" + queryString + "'";
        } catch (Exception ex) {
            isPassed = true;
            message = ex.getMessage();
        }
        verify(isPassed, message);
    }

    protected void assertValidQueryExecution(String queryString) {
        assertValidQueryExecutionWithArgs(queryString, new Object[0]);
    }

    private boolean isUtilDateLike(Object arg) {
        return arg instanceof java.util.Date || arg instanceof java.util.Calendar;
    }

    protected void assertValidQueryExecutionWithArgs(String queryString, Object... args) {
        EntityManager em = getEnvironment().getEntityManager();

        Query q = em.createQuery(queryString);

        // setting arguments
        if (args != null && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                if (!isUtilDateLike(args[i])) {
                    q.setParameter(i + 1, args[i]);
                } else {
                    throw new IllegalArgumentException(
                            "Currently, for this test-method the use of date-like input parameters is not supported");
                }
            }
        }
        q.getResultList();
    }

    protected enum ParameterType {
        NAMED, POSITIONAL
    }

    protected class InputParameterHolder {
        private boolean isTemporal = false;
        private ParameterType type;
        private final Object identitfier;
        private final Object value;
        private TemporalType temporalType;

        public InputParameterHolder(Object identifier, Object value, TemporalType temporalType) {
            this(identifier, value);
            this.temporalType = temporalType;
            isTemporal = true;
        }

        public InputParameterHolder(Object identifier, Object value) {
            this.identitfier = identifier;
            this.value = value;

            if (identifier instanceof String) {
                type = ParameterType.NAMED;
            } else if (identifier instanceof Integer) {
                type = ParameterType.POSITIONAL;
            } else {
                throw new IllegalArgumentException("InputParameterHolder was created with an illegal identifier: " + identifier
                        + ". Only String and Integer are allowed.");
            }
        }

        public Object getIdentitfier() {
            return identitfier;
        }

        public Object getValue() {
            return value;
        }

        public TemporalType getTemporalType() {
            return temporalType;
        }

        public ParameterType getType() {
            return type;
        }

        public boolean isTemporal() {
            return isTemporal;
        }
    }
}
