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

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.persistence.NoResultException;

import org.apache.openjpa.persistence.Extent;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAQuery;
import org.apache.openjpa.persistence.jdbc.FetchMode;
import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3;

/**
 * Test that ResultList objects behaver correctly.
 *
 * @author Marc Prud'hommeaux
 */
public class TestQueryResults extends BaseQueryTest {

    public TestQueryResults(String test) {
        super(test);
    }

    @Override
    public void setUp() {
        deleteAll(RuntimeTest1.class);

        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);
        em.persist(new RuntimeTest1("TestQueryResults1", 10));
        em.persist(new RuntimeTest1("TestQueryResults3", 10));
        em.persist(new RuntimeTest1("TestQueryResults5", 10));
        em.persist(new RuntimeTest3("TestQueryResults2", 10));
        em.persist(new RuntimeTest3("TestQueryResults4", 10));
        em.persist(new RuntimeTest3("TestQueryResults6", 10));
        endTx(em);
        endEm(em);
    }

    public void testQueryIteratorsReturnFalseForClosedQuery() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
        List c = q.getResultList();
        Iterator i = c.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        q.closeAll();
        endTx(em);
        endEm(em);

        if (i.hasNext())
            fail("Iterator obtained from Query should return false "
                + "for hasNext() after Query has been closed");
    }

    public void testQueryIteratorsThrowExceptionForClosedQuery() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
        List c = q.getResultList();
        Iterator i = c.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        q.closeAll();
        endTx(em);
        endEm(em);

        try {
            i.next();
            fail("Iterator.next() should have thrown Exception "
                + "after query.closeAll() was called");
        }
        catch (Exception e) {
            //
        }
    }

    public void testLazyQueryIteratorsReturnFalseForClosedem() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        String query = "SELECT o FROM RuntimeTest1 o";
        OpenJPAQuery q = em.createQuery(query);
        q.getFetchPlan().setFetchBatchSize(5);
        List c = q.getResultList();

        Iterator i = c.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        endTx(em);
        endEm(em);

        if (i.hasNext())
            fail("Lazy result iterator obtained from Query should return "
                + "false for hasNext() after em has been closed");
    }

    public void testEagerQueryIteratorsWorkForClosedem() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        String query = "SELECT o FROM RuntimeTest1 o";
        OpenJPAQuery q = em.createQuery(query);
        q.getFetchPlan().setFetchBatchSize(-1);

        List c = q.getResultList();

        Iterator i = c.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        endTx(em);
        endEm(em);

        if (!i.hasNext())
            fail("Eager result iterator obtained from Query should return "
                + "true for hasNext() after em has been closed");
    }

    public void testQueryResultIsList() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        String query = "SELECT o FROM RuntimeTest1 o";

        Collection c = (Collection) em.createQuery(query).getResultList();
        if (!(c instanceof List))
            fail("Collection (" + c.getClass() + ") should have "
                + "been a List instance");

        endTx(em);
        endEm(em);
    }

    public void testQueryResultSizeIsCorrect() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        em.persist(new RuntimeTest2("TestQueryResults1", 10));
        endTx(em);
        endEm(em);

        em = (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        String query = "SELECT r FROM RuntimeTest2 r WHERE r.stringField = "
            + "\'TestQueryResults1\'";
        List c = em.createQuery(query).getResultList();

        assertEquals(1, c.size());
        endTx(em);
        endEm(em);
    }

    public void testExtentIteratorsReturnFalseForClosedExtent() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);
        Extent extent = em.createExtent(RuntimeTest1.class, true);

        Iterator i = extent.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        extent.closeAll();

        if (i.hasNext())
            fail("Iterator obtained from Extent should return false "
                + "for hasNext() after Extent has been closed");

        endTx(em);
        endEm(em);
    }

    public void testExtentIteratorsThrowExceptionForClosedExtent() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        Extent extent = em.createExtent(RuntimeTest1.class, true);

        Iterator i = extent.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        extent.closeAll();

        try {
            i.next();
            fail("Iterator.next() should have thrown Exception "
                + "after Extent.closeAll() was called");
        } catch (Exception e) {
            // this is a *good* thing.
        }

        endTx(em);
        endEm(em);
    }

    public void testExtentIteratorsReturnFalseForClosedem() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        Extent extent = em.createExtent(RuntimeTest1.class, true);
        Iterator i = extent.iterator();
        if (!(i.hasNext()))
            fail("Iterator should have had next()");
        endTx(em);
        endEm(em);

        if (i.hasNext())
            fail("Iterator obtained from Extent should return false "
                + "for hasNext() after em has been closed");
    }

    public void testUniqueReturnsSingleResult() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        String query = "SELECT DISTINCT r FROM RuntimeTest1 r WHERE "
            + "r.stringField = \'TestQueryResults1\'";
        Object obj = em.createQuery(query).getSingleResult();

        assertTrue(obj instanceof RuntimeTest1);

        query = "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = "
            + "\'xxxx\'";
        OpenJPAQuery q = em.createQuery(query);
        try {
            Object l = q.getSingleResult();
            fail("Expected NoResultException since there is no RuntimeTest1 "
                 + "instance with stringfield=xxxx");
        } catch (NoResultException e) {
            // good
        }

        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testUniqueThrowsExceptionIfMultipleResults() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);
        String query = "SELECT DISTINCT r FROM RuntimeTest1 r";
        OpenJPAQuery q = em.createQuery(query);

        try {
            Object l = q.getSingleResult();
            fail("Unique query matched multiple results.");
        }
        catch (Exception jue) {
        }
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testImpossibleRangeReturnsEmptyList() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);
        String query = "SELECT r FROM RuntimeTest1 r";
        OpenJPAQuery q = em.createQuery(query);
        q.setFirstResult(2);
        q.setMaxResults(0);

        List results = q.getResultList();

        assertEquals(0, results.size());
        assertFalse(results.iterator().hasNext());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testImpossibleUniqueRangeReturnsNull() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r "
            + "WHERE r.stringField = \'TestQueryResults1\'");
        q.setFirstResult(2);
        q.setMaxResults(0);
        assertTrue(
            "resultlist is not null its size is: " + q.getResultList().size(),
            q.getResultList().isEmpty());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testSingleResultUniqueRange() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r "
            + "WHERE r.stringField = \'TestQueryResults1\'");
        q.setFirstResult(1);
        q.setMaxResults(1000000);

        assertTrue("resultlist is not empty", (q.getResultList()).isEmpty());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testMultiResultUniqueRange() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setFirstResult(1);
        q.setMaxResults(2);

        assertEquals("TestQueryResults2",
            ((RuntimeTest1) q.getResultList().get(0)).getStringField());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    /* This test is being commented because it was supposed to be a converted
     * test complementing the original JDO test which uses the setUnique()
     * method available in JDO Query. OpenJPAQuery does not have such a method
     * and hence this test does not make sense.
      public void testUniqueThrowsExceptionIfNonUniqueRange()
     {
         OpenJPAEntityManager em =
             (OpenJPAEntityManager) currentEntityManager();
         startTx(em);

         OpenJPAQuery q = em.createQuery(
            "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
         q.setFirstResult(1);
         q.setMaxResults(3);

         try
         {
             q.getResultList();
             fail("Unique allowed non-unique range.");
         }
         catch (Exception jue)
         {
         }
         q.closeAll();
         endTx(em);
         endEm(em);
     }
     */
    public void testFullRange() {
        try {
            OpenJPAEntityManager em =
                (OpenJPAEntityManager) currentEntityManager();
            startTx(em);

            OpenJPAQuery q = em.createQuery(
                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
            q.setSubclasses(false);
            q.setFirstResult(0);
            Long l = Long.MAX_VALUE;
            q.setMaxResults(l.intValue());

            List res = (List) q.getResultList();
            assertEquals(3, res.size());
            for (int i = 0; i < res.size(); i++)
                assertEquals("TestQueryResults" + (i * 2 + 1),
                    ((RuntimeTest1) res.get(i)).getStringField());
            q.closeAll();
            endTx(em);
            endEm(em);
        }
        catch (Exception uoe) {
            //FIXME:AFAM -- Figure out JPA Equivalence of createExtent(class,
            //false) ie how to restrict the query result to the base entity and
            //not the subclasses
        }
    }

    public void testFullRangeSubs() {
        try {
            OpenJPAEntityManager em =
                (OpenJPAEntityManager) currentEntityManager();
            startTx(em);

            OpenJPAQuery q = em.createQuery(
                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
            q.setFirstResult(0);
            Long l = Long.MAX_VALUE;
            q.setMaxResults(l.intValue());

            List res = (List) q.getResultList();
            assertEquals(6, res.size());
            for (int i = 0; i < res.size(); i++)
                assertEquals("TestQueryResults" + (i + 1),
                    ((RuntimeTest1) res.get(i)).getStringField());
            q.closeAll();
            endTx(em);
            endEm(em);
        }
        catch (Exception uoe) {
        }
    }

    public void testBeginRange() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setSubclasses(false);
        for (int i = 0; i < 4; i++) {
            q.setFirstResult(i);
            q.setMaxResults(100000);

            List res = (List) q.getResultList();
            assertEquals("they are not equal", 3 - i, res.size());
            int idx = 0;

            // try both random acess and iteration
            for (int j = 0; j < res.size(); j++)
                assertEquals("TestQueryResults" + (j * 2 + 1 + i * 2),
                    (((RuntimeTest1) res.get(j)).getStringField()));
            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
                assertEquals("TestQueryResults" + (idx * 2 + 1 + i * 2),
                    ((RuntimeTest1) itr.next()).getStringField());
        }
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testBeginRangeSubs() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");

        for (int i = 0; i < 7; i++) {
            q.setFirstResult(i);
            Long l = Long.MAX_VALUE;
            q.setMaxResults(100000);

            List res = (List) q.getResultList();
            assertEquals(6 - i, res.size());
            int idx = 0;

            // try both random acess and iteration
            for (int j = 0; j < res.size(); j++)
                assertEquals("TestQueryResults" + (j + 1 + i),
                    ((RuntimeTest1) res.get(j)).getStringField());
            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
                assertEquals("TestQueryResults" + (idx + 1 + i),
                    ((RuntimeTest1) itr.next()).getStringField());
        }
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testEndRange() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setSubclasses(false);

        for (int i = 0; i < 4; i++) {
            q.setFirstResult(0);
            q.setMaxResults(i);

            List res = (List) q.getResultList();
            assertEquals(i, res.size());
            int idx = 0;

            // try both random acess and iteration
            for (int j = 0; j < res.size(); j++)
                assertEquals("TestQueryResults" + (j * 2 + 1),
                    ((RuntimeTest1) res.get(j)).getStringField());
            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
                assertEquals("TestQueryResults" + (idx * 2 + 1),
                    ((RuntimeTest1) itr.next()).getStringField());
        }
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testEndRangeSubs() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");

        for (int i = 0; i < 7; i++) {
            q.setFirstResult(0);
            q.setMaxResults(i);
            List res = (List) q.getResultList();
            assertEquals(i, res.size());
            int idx = 0;

            // try both random acess and iteration
            for (int j = 0; j < res.size(); j++)
                assertEquals("TestQueryResults" + (j + 1),
                    ((RuntimeTest1) res.get(j)).getStringField());
            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
                assertEquals("TestQueryResults" + (idx + 1),
                    ((RuntimeTest1) itr.next()).getStringField());
        }
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testMidRange() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setSubclasses(false);

        q.setFirstResult(1);
        q.setMaxResults(3);
        List res = (List) q.getResultList();
        assertEquals(2, res.size());
        for (int i = 0; i < res.size(); i++)
            assertEquals("TestQueryResults" + (i * 2 + 1 + 2),
                ((RuntimeTest1) res.get(i)).getStringField());
        int idx = 0;
        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
            assertEquals("TestQueryResults" + (idx * 2 + 1 + 2),
                ((RuntimeTest1) itr.next()).getStringField());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testMidRangeSubs() {
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setFirstResult(1);
        q.setMaxResults(3);

        List res = (List) q.getResultList();
        assertEquals(3, res.size());
        for (int i = 0; i < res.size(); i++)
            assertEquals("TestQueryResults" + (i + 1 + 1),
                ((RuntimeTest1) res.get(i)).getStringField());
        int idx = 0;
        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
            assertEquals("TestQueryResults" + (idx + 1 + 1),
                ((RuntimeTest1) itr.next()).getStringField());
        q.closeAll();
        endTx(em);
        endEm(em);
    }

    public void testPessimisticOrderedRange() {
        // test to make sure whatever machinations we do to get a range doesn't
        // interfere with FOR UPDATE
        OpenJPAEntityManager em =
            (OpenJPAEntityManager) currentEntityManager();
        startTx(em);

        OpenJPAQuery q = em.createQuery(
            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
        q.setSubclasses(false);
        q.setFirstResult(0);
        q.setMaxResults(2);

        ((JDBCFetchPlan) q.getFetchPlan()).setEagerFetchMode(FetchMode.NONE);

        List res = (List) q.getResultList();
        assertEquals(2, res.size());
        assertEquals("TestQueryResults1",
            ((RuntimeTest1) res.get(0)).getStringField());
        assertEquals("TestQueryResults3",
            ((RuntimeTest1) res.get(1)).getStringField());
        q.closeAll();
        endTx(em);
        endEm(em);
    }
}

