/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.persistence.criteria;

import jakarta.persistence.EntityManager;

import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.criteria.results.Bar;
import org.apache.openjpa.persistence.criteria.results.Foo;

/**
 * Generic utility to run Criteria tests.
 *
 * Provides facility to compare the target SQL generated by good old JPQL and newly minted Criteria.
 *
 */
public abstract class CriteriaTest extends AbstractCriteriaTestCase {
    protected static OpenJPAEntityManagerFactorySPI emf;
    protected static SQLAuditor auditor;

    protected OpenJPACriteriaBuilder cb;
    protected EntityManager em;

    protected static Class<?>[] CLASSES =
        { Account.class, Address.class, A.class, B.class, CompUser.class, Contact.class, Contractor.class,
            Course.class, CreditCard.class, Customer.class, C.class, Department.class, DependentId.class,
            Dependent.class, D.class, Employee.class, Exempt.class, FemaleUser.class, FrequentFlierPlan.class,
            Item.class, LineItem.class, Magazine.class, MaleUser.class, Manager.class, Movie.class, Order.class,
            Person.class, Phone.class, Photo.class, Product.class, Publisher.class, Request.class, Semester.class,
            Student.class, TransactionHistory.class, Transaction.class, VideoStore.class, Foo.class, Bar.class,
            EntityWithIdClass.class};

    protected Class<?>[] getDomainClasses() {
        return CLASSES;
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        if (getEntityManagerFactory() == null) {
            auditor = new SQLAuditor();
            setEntityManagerFactory(createNamedEMF(getDomainClasses()));
            assertNotNull(getEntityManagerFactory());
        }
        setDictionary();
        em = getEntityManagerFactory().createEntityManager();
        cb = getEntityManagerFactory().getCriteriaBuilder();
    }

    @Override
    public void tearDown() throws Exception {
        if (em != null && em.isOpen()) {
            em.close();
            em = null;
        }
        cb = null;
        auditor.clear();
        auditor = null;
        if (emf != null && emf.isOpen()) {
            emf.close();
            emf = null;
        }
        super.tearDown();
    }

    @Override
    protected OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
        return emf;
    }

    protected void setEntityManagerFactory(OpenJPAEntityManagerFactorySPI emf) {
        CriteriaTest.emf = emf;
    }

    @Override
    protected SQLAuditor getAuditor() {
        return auditor;
    }

    protected void setAuditor(SQLAuditor auditor) {
        CriteriaTest.auditor = auditor;
    }

    protected OpenJPACriteriaBuilder getCriteriaBuilder() {
        return cb;
    }

    protected void setCriteriaBuilder(OpenJPACriteriaBuilder cb) {
        this.cb = cb;
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    protected void setEntityManager(EntityManager em) {
        this.em = em;
    }

}
