/*
 * 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.MongoDatabaseConnection;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseConnectionFactory;
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.Mongo3ConnectionSpec;
import org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform;
import org.eclipse.persistence.sessions.DataRecord;
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.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoDatabase;

/**
 * TestSuite to test MongoDB database.
 * To run this test suite the MongoDB must be running.
 */
public class MongoDatabaseTestSuite 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);
    private static final String SERVER_SELECTION_TIMEOUT_PROPERTY = PersistenceUnitProperties.NOSQL_PROPERTY
            + Mongo3ConnectionSpec.SERVER_SELECTION_TIMEOUT;
    private static final String SERVER_SELECTION_TIMEOUT = "100";

    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 MongoDatabaseTestSuite() {
        properties = initProperties();
    }

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

    boolean isEnabled() {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            MongoDatabaseConnection con = ((MongoDatabaseConnection)em.unwrap(jakarta.resource.cci.Connection.class));
            String version = con.getMetaData().getEISProductVersion();
            return version.compareTo("2.6") > 0;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    /**
     * 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("MongoDatabaseTestSuite");
        MongoDatabaseTestSuite testSetup = new MongoDatabaseTestSuite("testSetup");
        if (testSetup.isEnabled()) {
            suite.addTest(testSetup);
            suite.addTest(new MongoDatabaseTestSuite("testInsert"));
            suite.addTest(new MongoDatabaseTestSuite("testFind"));
            suite.addTest(new MongoDatabaseTestSuite("testUpdate"));
            suite.addTest(new MongoDatabaseTestSuite("testUpdateAdd"));
            suite.addTest(new MongoDatabaseTestSuite("testMerge"));
            suite.addTest(new MongoDatabaseTestSuite("testLockError"));
            suite.addTest(new MongoDatabaseTestSuite("testRefresh"));
            suite.addTest(new MongoDatabaseTestSuite("testDelete"));
            suite.addTest(new MongoDatabaseTestSuite("testSimpleJPQL"));
            suite.addTest(new MongoDatabaseTestSuite("testJPQLLike"));
            suite.addTest(new MongoDatabaseTestSuite("testComplexJPQL"));
            suite.addTest(new MongoDatabaseTestSuite("testJPQLEnum"));
            suite.addTest(new MongoDatabaseTestSuite("testNativeQuery"));
            suite.addTest(new MongoDatabaseTestSuite("testExternalFactory"));
            suite.addTest(new MongoDatabaseTestSuite("testUserPassword"));
            suite.addTest(new MongoDatabaseTestSuite("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);
        MongoDatabase db = ((MongoDatabaseConnection)em.unwrap(jakarta.resource.cci.Connection.class)).getDB();
        db.drop();
        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();
        MongoClient mongo = new MongoClient();
        MongoDatabase db = mongo.getDatabase("mydb");
        properties.put(PersistenceUnitProperties.NOSQL_CONNECTION_FACTORY, new MongoDatabaseConnectionFactory(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");
        properties.put(SERVER_SELECTION_TIMEOUT_PROPERTY, SERVER_SELECTION_TIMEOUT);
        boolean errorCaught = false;
        EntityManagerFactory factory = null;
        EntityManager em = null;
        try {
            factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            em = factory.createEntityManager();
        } catch (Exception expected) {
            //Different MONGO DB drivers (versions) prints different error messages
            if (expected.getMessage().indexOf("Authentication failed") == -1 && expected.getMessage().indexOf("auth failed") == -1 && expected.getMessage().indexOf("Exception authenticating") == -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");
        properties.put(SERVER_SELECTION_TIMEOUT_PROPERTY, SERVER_SELECTION_TIMEOUT);
        errorCaught = false;
        factory = null;
        em = null;
        try {
            factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            em = factory.createEntityManager();
        } catch (Exception expected) {
            //Different MONGO DB drivers (versions) prints different error messages
            if (expected.getMessage().indexOf("Authentication failed") == -1 && expected.getMessage().indexOf("auth failed") == -1 && expected.getMessage().indexOf("Exception authenticating") == -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 DataRecord))
                || !(((DataRecord)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();
        }
    }

}
