/*
 * Copyright (c) 2011, 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:
//     Oracle - initial API and implementation
package org.eclipse.persistence.testing.tests.jpa.mongo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;

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

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.eis.interactions.MappedInteraction;
import org.eclipse.persistence.eis.interactions.QueryStringInteraction;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoConnection;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoConnectionFactory;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoOperation;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper;
import org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.testing.models.jpa.mongo.Address;
import org.eclipse.persistence.testing.models.jpa.mongo.Address.AddressType;
import org.eclipse.persistence.testing.models.jpa.mongo.Buyer;
import org.eclipse.persistence.testing.models.jpa.mongo.Customer;
import org.eclipse.persistence.testing.models.jpa.mongo.LineItem;
import org.eclipse.persistence.testing.models.jpa.mongo.Order;

import com.mongodb.DB;
import com.mongodb.Mongo;
import com.mongodb.MongoClientURI;

/**
 * TestSuite to test MongoDB database.
 * To run this test suite the MongoDB must be running.
 */
public class MongoTestSuite extends JUnitTestCase {

    /** The persistence unit name. */
    private static final String PU_NAME = "mongo";
    /** The persistence unit property key for the MongoDB connection host name or IP. */
    private static final String PROPERTY_HOST_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.host";
    /** The persistence unit property key for the MongoDB connection port. */
    private static final String PROPERTY_PORT_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.port";
    /** The persistence unit property key for the MongoDB database name. */
    private static final String PROPERTY_DB_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.db";
    /** The database (MongoDB) connection URL. */
    private static final String DB_URL_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_URL_KEY, null);
    /** The database (MongoDB) connection user name test configuration property key. */
    private static final String DB_USER_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_USER_KEY, null);
    /** The database (MongoDB) connection user password test configuration property key. */
    private static final String DB_PWD_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_PWD_KEY, null);
    /** The database (MongoDB) platform class test configuration property key. */
    private static final String DB_PLATFORM_KEY
            = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_PLATFORM_KEY, null);
    /** The test configuration property key of the EISConnectionSpec class name used to connect to the MongoDB
     *  data source. */
    private static final String DB_SPEC_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_SPEC_KEY, null);

    public static Order existingOrder;

    /** The MongoDB persistence unit properties {@link Map} from the test properties {@code db.<name>}. */
    private final Map<String, String> properties;

    /**
     * Create an instance of MongoDB database test suite.
     */
    public MongoTestSuite() {
        properties = initProperties();
    }

    /**
     * Create an instance of MongoDB database test suite.
     * @param name Test suite name.
     */
    public MongoTestSuite(String name){
        super(name);
        properties = initProperties();
    }

    /**
     * Build MongoDB database test suite. Creates an instance of the {@link TestSuite} class and adds all the tests
     * into it.
     * @return MongoDB database test suite with all the tests.
     */
    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("MongoTestSuite");
        suite.addTest(new MongoTestSuite("testSetup"));
        suite.addTest(new MongoTestSuite("testInsert"));
        suite.addTest(new MongoTestSuite("testFind"));
        suite.addTest(new MongoTestSuite("testUpdate"));
        suite.addTest(new MongoTestSuite("testUpdateAdd"));
        suite.addTest(new MongoTestSuite("testMerge"));
        suite.addTest(new MongoTestSuite("testLockError"));
        suite.addTest(new MongoTestSuite("testRefresh"));
        suite.addTest(new MongoTestSuite("testDelete"));
        suite.addTest(new MongoTestSuite("testSimpleJPQL"));
        suite.addTest(new MongoTestSuite("testJPQLLike"));
        suite.addTest(new MongoTestSuite("testComplexJPQL"));
        suite.addTest(new MongoTestSuite("testJPQLEnum"));
        suite.addTest(new MongoTestSuite("testNativeQuery"));
        suite.addTest(new MongoTestSuite("testExternalFactory"));
        suite.addTest(new MongoTestSuite("testUserPassword"));
        suite.addTest(new MongoTestSuite("testDynamicEntities"));
        return suite;
    }

    /**
     * Get the name of the persistence unit used in the tests.
     * @return The name of the persistence unit used in the tests.
     */
    @Override
    public String getPersistenceUnitName() {
        return PU_NAME;
    }

    /**
     * Build MongoDB persistence unit properties {@link Map} from test properties {@code db.<name>}.
     * @return Persistence unit properties {@link Map}.
     */
    private static Map<String, String> initProperties() {
        final Map<String, String> properties = new HashMap<>();
        final String dbUrl = JUnitTestCaseHelper.getProperty(DB_URL_KEY);
        final String dbUser = JUnitTestCaseHelper.getProperty(DB_USER_KEY);
        final String dbPwd = JUnitTestCaseHelper.getProperty(DB_PWD_KEY);
        final String platform = JUnitTestCaseHelper.getProperty(DB_PLATFORM_KEY);
        final String dbSpec = JUnitTestCaseHelper.getProperty(DB_SPEC_KEY);
        final String logLevel = JUnitTestCaseHelper.getProperty(JUnitTestCaseHelper.LOGGING_LEVEL_KEY);
        String uriUser = null;
        char[] uriPwd = null;
        if (dbUrl != null) {
            final MongoClientURI uri = new MongoClientURI(dbUrl);
            final List<String> hosts = uri.getHosts();
            final String name = uri.getDatabase();
            uriUser = uri.getUsername();
            uriPwd = uri.getPassword();
            if (hosts.size() > 0) {
                final String hostPort = hosts.get(0);
                final int splitPos = hostPort.indexOf(':');
                if (splitPos >= 0) {
                    final String host = hostPort.substring(0, splitPos);
                    final String port = hostPort.substring(splitPos);
                    properties.put(PROPERTY_HOST_KEY, host);
                    if (port != null && port.length() > 0) {
                        properties.put(PROPERTY_PORT_KEY, port);
                    }
                } else {
                    properties.put(PROPERTY_HOST_KEY, hostPort);
                }
            }
            if (name != null && name.length() > 0) {
                properties.put(PROPERTY_DB_KEY, name);
            }
        }
        // Database connection user name from db.user has higher priority than from URL.
        if (dbUser != null) {
            properties.put(PersistenceUnitProperties.JDBC_USER, dbUser);
        } else if (uriUser != null && uriUser.length() > 0) {
            properties.put(PersistenceUnitProperties.JDBC_USER, uriUser);
        }
        // Database connection user password from db.pwd has higher priority than from URL.
        if (dbPwd != null) {
            properties.put(PersistenceUnitProperties.JDBC_PASSWORD, dbPwd);
        } else if (uriPwd != null && uriPwd.length > 0) {
            properties.put(PersistenceUnitProperties.JDBC_PASSWORD, new String(uriPwd));
        }
        if (platform != null) {
            properties.put(PersistenceUnitProperties.TARGET_DATABASE, platform);
        }
        if (dbSpec != null) {
            properties.put(PersistenceUnitProperties.NOSQL_CONNECTION_SPEC, dbSpec);
        }
        if (logLevel != null) {
            properties.put(PersistenceUnitProperties.LOGGING_LEVEL, logLevel);
        }
        return properties;
    }

    /**
     * Update the connection user name persistence unit property value.
     * @param properties The properties {@link Map} to be modified.
     * @param key The connection user name persistence unit property key ({@code PersistenceUnitProperties.JDBC_USER}
     *            or {@code PersistenceUnitProperties.NOSQL_USER)}).
     * @param value The connection user name persistence unit property value.
     */
    private static void updateUserProperty(
            final Map<String, String> properties, final String key, final String value) {
        if (key.equals(PersistenceUnitProperties.JDBC_USER)
                || key.equals(PersistenceUnitProperties.NOSQL_USER)) {
            properties.remove(PersistenceUnitProperties.JDBC_USER);
            properties.remove(PersistenceUnitProperties.NOSQL_USER);
            properties.put(key, value);
        } else {
            throw new IllegalArgumentException("Invalid user persistence property key");
        }
    }

    /**
     * Update the connection user password persistence unit property value.
     * @param properties The properties {@link Map} to be modified.
     * @param key The connection user name persistence unit property key ({@code PersistenceUnitProperties.JDBC_PASSWORD}
     *            or {@code PersistenceUnitProperties.NOSQL_PASSWORD)}).
     * @param value The connection user name persistence unit property value.
     */
    private static void updatePasswordProperty(
            final Map<String, String> properties, final String key, final String value) {
        if (key.equals(PersistenceUnitProperties.JDBC_PASSWORD)
                || key.equals(PersistenceUnitProperties.NOSQL_PASSWORD)) {
            properties.remove(PersistenceUnitProperties.JDBC_PASSWORD);
            properties.remove(PersistenceUnitProperties.NOSQL_PASSWORD);
            properties.put(key, value);
        } else {
            throw new IllegalArgumentException("Invalid user persistence property key");
        }
    }

    /**
     * Get the MongoDB persistence unit properties {@link Map}.
     * @return The MongoDB persistence unit properties {@link Map}.
     */
    @Override
    public Map<String, String> getPersistenceProperties() {
        return properties;
    }

    /**
     * Initialize test suite.
     */
    public void testSetup() {
        EntityManager em = createEntityManager();
        // First clear old database.
        beginTransaction(em);
        DB db = ((MongoConnection)em.unwrap(jakarta.resource.cci.Connection.class)).getDB();
        db.dropDatabase();
        commitTransaction(em);
        beginTransaction(em);
        try {
            for (int index = 0; index < 10; index++) {
                existingOrder = new Order();
                existingOrder.orderedBy = "ACME";
                existingOrder.address = new Address();
                existingOrder.address.city = "Ottawa";
                existingOrder.address.addressee = "Bob Jones";
                existingOrder.address.state = "CA";
                existingOrder.address.country = "Mexico";
                existingOrder.address.zipCode = "12345";
                LineItem line = new LineItem();
                line.itemName = "stuff";
                line.itemPrice = new BigDecimal("10.99");
                line.lineNumber = 1;
                line.quantity = 100;
                existingOrder.lineItems.add(line);
                line = new LineItem();
                line.itemName = "more stuff";
                line.itemPrice = new BigDecimal("20.99");
                line.lineNumber = 2;
                line.quantity = 50;
                existingOrder.lineItems.add(line);
                existingOrder.comments.add("priority order");
                existingOrder.comments.add("next day");
                em.persist(existingOrder);
            }
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
    }

    /**
     * Test inserts.
     */
    public void testInsert() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            order.address.type = AddressType.Work;

            LineItem item = new LineItem();
            item.itemName = "stuff";
            item.itemPrice = new BigDecimal("9.99");
            item.lineNumber = 1;
            item.quantity = 50;
            order.lineItems.add(item);

            item = new LineItem();
            item.itemName = "more stuff";
            item.itemPrice = new BigDecimal(500);
            item.lineNumber = 2;
            item.quantity = 1;
            order.lineItems.add(item);

            item = new LineItem();
            item.itemName = "stuff";
            item.itemPrice = new BigDecimal("9.99");
            item.lineNumber = 1;
            item.quantity = 50;
            order.lineItemsByNumber.put(1L, item);

            item = new LineItem();
            item.itemName = "more stuff";
            item.itemPrice = new BigDecimal(500);
            item.lineNumber = 2;
            item.quantity = 1;
            order.lineItemsByNumber.put(2L, item);

            em.persist(order);

            Customer customer = new Customer();
            customer.name = "ACME";
            em.persist(customer);
            order.customer = customer;
            order.customers.add(customer);
            customer = new Customer();
            customer.name = "Startup";
            em.persist(customer);
            order.customers.add(customer);

            Buyer buyer = new Buyer();
            buyer.id1 = 1;
            buyer.id2 = 1;
            buyer.name = "FOO Inc.";
            em.persist(buyer);
            order.buyer = buyer;
            order.buyers.add(buyer);
            buyer = new Buyer();
            buyer.id1 = 2;
            buyer.id2 = 2;
            buyer.name = "BAR Corp.";
            em.persist(buyer);
            order.buyers.add(buyer);

            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        verifyObjectInCacheAndDatabase(order);
        verifyObjectInEntityManager(order);
    }

    /**
     * Test pass an external factory when connecting.
     */
    public void testExternalFactory() throws Exception {
        Map properties = new HashMap();
        Mongo mongo = new Mongo();
        DB db = mongo.getDB("mydb");
        properties.put(PersistenceUnitProperties.NOSQL_CONNECTION_FACTORY, new MongoConnectionFactory(db));
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
        EntityManager em = factory.createEntityManager();
        em.close();
        factory.close();
        mongo.close();
    }

    /**
     * Test user/password connecting.
     */
    public void testUserPassword() throws Exception {
        Map<String, String> properties = new HashMap<String, String>(this.properties);
        updateUserProperty(properties, PersistenceUnitProperties.JDBC_USER, "unknownuser");
        updatePasswordProperty(properties, PersistenceUnitProperties.JDBC_PASSWORD, "password");
        boolean errorCaught = false;
        EntityManagerFactory factory = null;
        EntityManager em = null;
        try {
            factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            em = factory.createEntityManager();
        } catch (Exception expected) {
            if (expected.getMessage().indexOf("authenticate") == -1) {
                throw expected;
            }
            errorCaught = true;
        } finally {
            if (em != null) {
                em.close();
            }
            if (factory != null) {
                factory.close();
            }
        }
        if (!errorCaught) {
            fail("authentication should have failed");
        }
        properties = new HashMap<String, String>(this.properties);
        updateUserProperty(properties, PersistenceUnitProperties.NOSQL_USER, "unknownuser");
        updatePasswordProperty(properties, PersistenceUnitProperties.NOSQL_PASSWORD, "password");
        errorCaught = false;
        factory = null;
        em = null;
        try {
            factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            em = factory.createEntityManager();
        } catch (Exception expected) {
            if (expected.getMessage().indexOf("authenticate") == -1) {
                throw expected;
            }
            errorCaught = true;
        } finally {
            if (em != null) {
                em.close();
            }
            if (factory != null) {
                factory.close();
            }
        }
        if (!errorCaught) {
            fail("authentication should have failed");
        }
    }

    /**
     * Test find.
     */
    public void testFind() {
        clearCache();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = null;
        try {
            order = em.find(Order.class, existingOrder.id);
            compareObjects(existingOrder, order);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    /**
     * Test updates.
     */
    public void testUpdate() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            order = em.find(Order.class, order.id);
            order.orderedBy = "Fred Jones";
            order.address.addressee = "Fred Jones";
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        verifyObjectInCacheAndDatabase(order);
        verifyObjectInEntityManager(order);
    }


    /**
     * Test updates.
     */
    public void testUpdateAdd() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            order = em.find(Order.class, order.id);
            Customer customer = new Customer();
            em.persist(customer);
            order.customers.add(customer);
            order.comments.add("foo");
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        verifyObjectInCacheAndDatabase(order);
        verifyObjectInEntityManager(order);
    }

    /**
     * Test merge.
     */
    public void testMerge() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            order = em.find(Order.class, order.id);
            order.orderedBy = "Fred Jones";
            order.address.addressee = "Fred Jones";
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        em = createEntityManager();
        beginTransaction(em);
        try {
            em.merge(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            Order fromDatabase = em.find(Order.class, order.id);
            order.version = order.version + 1;
            compareObjects(order, fromDatabase);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    /**
     * Test locking.
     */
    public void testLockError() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            Order updatedOrder = em.find(Order.class, order.id);
            updatedOrder.orderedBy = "Fred Jones";
            updatedOrder.address.addressee = "Fred Jones";
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        OptimisticLockException exception = null;
        em = createEntityManager();
        beginTransaction(em);
        try {
            em.merge(order);
            commitTransaction(em);
        } catch (OptimisticLockException expected) {
            exception = expected;
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        if (exception == null) {
            fail("Lock error did not occur.");
        }
    }

    /**
     * Test refresh.
     */
    public void testRefresh() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            order = em.find(Order.class, order.id);
            order.orderedBy = "Fred Jones";
            em.refresh(order);
            if (order.orderedBy.equals("Fred Jones")) {
                fail("Refresh failed: " + order.orderedBy);
            }
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    /**
     * Test JPQL.
     */
    public void testSimpleJPQL() {
        // Clear db first.
        testSetup();
        EntityManager em = createEntityManager();
        try {
            // all
            Query query = em.createQuery("Select o from Order o");
            List results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 results: " + results);
            }
            Order order = (Order)results.get(0);
            // =
            query = em.createQuery("Select o from Order o where o.id = :oid");
            query.setParameter("oid", order.id);
            results = query.getResultList();
            if (results.size() != 1) {
                fail("Expected 1 result: " + results);
            }
            // !=
            query = em.createQuery("Select o from Order o where o.id <> :nextId");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 9) {
                fail("Expected 9 result: " + results);
            }
            // in
            query = em.createQuery("Select o from Order o where o.orderedBy in (:by, :by)");
            query.setParameter("by", "ACME");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 1 result: " + results);
            }
            // nin
            query = em.createQuery("Select o from Order o where o.orderedBy not in (:by, :by)");
            query.setParameter("by", "ACME");
            results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
            // and
            query = em.createQuery("Select o from Order o where o.id = :nextId and o.orderedBy = 'ACME'");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 1) {
                fail("Expected 1 result: " + results);
            }
            // or
            query = em.createQuery("Select o from Order o where o.id = :nextId or o.orderedBy = 'ACME'");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            // not
            query = em.createQuery("Select o from Order o where o.id = :nextId or not(o.orderedBy = 'ACME')");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 1) {
                fail("Expected 1 result: " + results);
            }
            // not + operator
            query = em.createQuery("Select o from Order o where o.id = :nextId or not(o.id <> :nextId)");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 1) {
                fail("Expected 10 result: " + results);
            }
            // > <
            query = em.createQuery("Select o from Order o where o.id > :nextId and o.id < :nextId");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
            // >= <=
            query = em.createQuery("Select o from Order o where o.id >= :nextId and o.id <= :nextId");
            query.setParameter("nextId", order.id);
            results = query.getResultList();
            if (results.size() != 1) {
                fail("Expected 1 result: " + results);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test JPQL.
     */
    public void testComplexJPQL() {
        // Clear db first.
        testSetup();
        EntityManager em = createEntityManager();
        try {
            // embedded
            Query query = em.createQuery("Select o from Order o where o.address.city = :city");
            query.setParameter("city", "Ottawa");
            List results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query = em.createQuery("Select o from Order o join o.lineItems l where l.itemName = :name");
            query.setParameter("name", "stuff");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            // order by
            query = em.createQuery("Select o from Order o order by o.address.city");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query = em.createQuery("Select o from Order o order by o.orderedBy desc");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query = em.createQuery("Select o from Order o order by o.orderedBy desc, o.address.city desc");
            //query = em.createQuery("Select o from Order o order by o.orderedBy desc, o.address.city asc");
            // Can't seem to order asc and desc at same time.
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            // select
            query = em.createQuery("Select o.id from Order o where o.orderedBy like :orderedBy");
            query.setParameter("orderedBy", "ACME");
            results = query.getResultList();
            if (!(results.get(0) instanceof String)) {
                fail("Incorrect result: " + results);
            }
            query = em.createQuery("Select o.id, o.address.city from Order o where o.orderedBy like :orderedBy");
            query.setParameter("orderedBy", "ACME");
            results = query.getResultList();
            if (!(results.get(0) instanceof Object[])) {
                fail("Incorrect result: " + results);
            }
            // error
            try {
                query = em.createQuery("Select count(o) from Order o");
                query.setParameter("orderedBy", "ACME");
                results = query.getResultList();
                fail("Exception expected");
            } catch (Exception expected) {
                // OK
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test JPQL.
     */
    public void testJPQLLike() {
        // Clear db first.
        testSetup();
        EntityManager em = createEntityManager();
        try {
            // like
            Query query = em.createQuery("Select o from Order o where o.orderedBy like :orderedBy");
            query.setParameter("orderedBy", "ACME");
            List results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query.setParameter("orderedBy", "A%");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query.setParameter("orderedBy", "%");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query.setParameter("orderedBy", "A__E");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
            query.setParameter("orderedBy", "*");
            results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
            query.setParameter("orderedBy", "A");
            results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
            query.setParameter("orderedBy", "");
            results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
            query.setParameter("orderedBy", "%E");
            results = query.getResultList();
            if (results.size() != 10) {
                fail("Expected 10 result: " + results);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test enum query.
     */
    public void testJPQLEnum() {
        // Clear db first.
        testSetup();
        EntityManager em = createEntityManager();
        try {
            // like
            Query query = em.createQuery("Select o from Order o where o.address.type = :type");
            query.setParameter("type", AddressType.Home);
            List results = query.getResultList();
            if (results.size() != 0) {
                fail("Expected 0 result: " + results);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test native query.
     */
    public void testNativeQuery() {
        EntityManager em = createEntityManager();

        MappedInteraction interaction = new MappedInteraction();
        interaction.setProperty(MongoPlatform.OPERATION, MongoOperation.FIND.name());
        interaction.setProperty(MongoPlatform.COLLECTION, "ORDER");
        interaction.setProperty(MongoPlatform.BATCH_SIZE, "10");
        interaction.setProperty(MongoPlatform.READ_PREFERENCE, "PRIMARY");
        interaction.addArgumentValue("_id", existingOrder.id);
        Query query = em.unwrap(JpaEntityManager.class).createQuery(interaction);
        List result = query.getResultList();
        if ((result.size() != 1)
                || (!(result.get(0) instanceof Record))
                || !(((Record)result.get(0)).get("_id").equals(existingOrder.id))) {
            fail("Incorrect result: " + result);
        }

        interaction = new MappedInteraction();
        interaction.setProperty(MongoPlatform.OPERATION, MongoOperation.FIND.name());
        interaction.setProperty(MongoPlatform.COLLECTION, "ORDER");
        interaction.setProperty(MongoPlatform.BATCH_SIZE, "10");
        interaction.setProperty(MongoPlatform.READ_PREFERENCE, "PRIMARY");
        interaction.addArgumentValue("_id", existingOrder.id);
        query = em.unwrap(JpaEntityManager.class).createQuery(interaction, Order.class);
        Order order = (Order)query.getSingleResult();
        if ((order == null) || (!order.id.equals(existingOrder.id))) {
            fail("Incorrect result: " + order);
        }

        QueryStringInteraction mqlInteraction = new QueryStringInteraction();
        mqlInteraction.setQueryString("db.ORDER.findOne({\"_id\":\"" + existingOrder.id + "\"})");
        query = em.unwrap(JpaEntityManager.class).createQuery(mqlInteraction, Order.class);
        order = (Order)query.getSingleResult();
        if ((order == null) || (!order.id.equals(existingOrder.id))) {
            fail("Incorrect result: " + order);
        }

        query = em.createNativeQuery("db.ORDER.findOne({\"_id\":\"" + existingOrder.id + "\"})", Order.class);
        order = (Order)query.getSingleResult();
        if ((order == null) || (!order.id.equals(existingOrder.id))) {
            fail("Incorrect result: " + order);
        }

    }

    /**
     * Test deletes.
     */
    public void testDelete() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Order order = new Order();
        try {
            order.orderedBy = "ACME";
            order.address = new Address();
            order.address.city = "Ottawa";
            em.persist(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            order = em.find(Order.class, order.id);
            em.remove(order);
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        try {
            Order fromDatabase = em.find(Order.class, order.id);
            if (fromDatabase != null) {
                fail("Object not deleted: " + fromDatabase);
            }
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    /**
     * Test dynamic entities.
     */
    public void testDynamicEntities() {
        final Map<String, Object> properties = new HashMap<>(this.properties);
        properties.put("eclipselink.classloader", new DynamicClassLoader(getClass().getClassLoader()));
        properties.put("eclipselink.logging.level", "finest");
        final EntityManagerFactory factory = Persistence.createEntityManagerFactory("mongo-dynamic", properties);
        final EntityManager em = factory.createEntityManager();
        beginTransaction(em);
        try {
            JPADynamicHelper helper = new JPADynamicHelper(em);
            final DynamicEntity person = helper.newDynamicEntity("Person");
            person.set("firstname", "Boy");
            person.set("lastname", "Pelletier");
            DynamicEntity address = helper.newDynamicEntity("org.eclipse.persistence.testing.models.jpa.nosql.dynamic.Address");
            address.set("city", "Ottawa");
            List<DynamicEntity> addresses = new ArrayList<>();
            addresses.add(address);
            person.set("addresses", addresses);
            em.persist(person);
            commitTransaction(em);

            em.createNamedQuery("Person.findAll").getResultList();

            beginTransaction(em);
            address = helper.newDynamicEntity("org.eclipse.persistence.testing.models.jpa.nosql.dynamic.Address");
            address.set("city", "Ottawa2");
            addresses = person.get("addresses");
            addresses.add(address);
            person.set("addresses", addresses);
            commitTransaction(em);

            factory.getCache().evictAll();
            em.clear();
            final DynamicEntity dbPerson = em.find(helper.getType("Person").getJavaClass(), person.get("id"));
            if (((Collection)dbPerson.get("addresses")).size() != 2) {
                fail("Expected 2 addresses: " + dbPerson.get("addresses"));
            }
        } finally {
            closeEntityManagerAndTransaction(em);
            factory.close();
        }
    }

}
