/*
 * 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.usergrid.rest.applications.queries;


import org.apache.usergrid.rest.test.resource.model.Collection;
import org.apache.usergrid.rest.test.resource.model.Entity;
import org.apache.usergrid.rest.test.resource.model.QueryParameters;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

import static org.junit.Assert.*;


/**
 * // TODO: Document this
 *
 * @since 4.0
 */
public class AndOrQueryTest extends QueryTestBase {
    private static final Logger logger = LoggerFactory.getLogger(AndOrQueryTest.class);


    /**
     * Test an inclusive AND query to ensure the correct results are returned
     *
     * @throws IOException
     */
    @Test
    public void queryAndInclusive() throws IOException {
        int numOfEntities = 20;
        String collectionName = "apples";
        // create our test entities
        generateTestEntities(numOfEntities, collectionName);
        // Query where madeup = true (the last half) and the last quarter of entries
        QueryParameters params = new QueryParameters()
            .setQuery("select * where madeup = true AND ordinal >= " + (numOfEntities - numOfEntities / 4));
        Collection coll = this.app().collection(collectionName).get(params);
        // results should have madeup = true and ordinal 15-19
        assertEquals(numOfEntities / 4, coll.getResponse().getEntityCount());
        // loop though entities that were returned, and test against the ordinals and values we are
        // expecting, starting with the last entity and decrementing
        int index = 19;
        while (coll.hasNext()) {
            Entity activity = coll.next();
            // ensure the 'madeup' property is set to true
            assertTrue(Boolean.parseBoolean(activity.get("madeup").toString()));
            // make sure the correct ordinal properties are returned
            assertEquals(index--, Long.parseLong(activity.get("ordinal").toString()));
        }

    }
    @Test
    public void someTestProp() throws IOException {
        int numOfEntities = 20;
        String collectionName = "bananas";
        // create our test entities
        generateTestEntities(numOfEntities, collectionName);
        // Query where madeup = true (the last half) and the last quarter of entries
        QueryParameters params = new QueryParameters()
            .setQuery("where sometestprop = 'testprop'");
        Collection coll = this.app().collection(collectionName).get(params);
        // results should have madeup = true and ordinal 15-19
        assertEquals(10, coll.getResponse().getEntityCount());


    }

    @Test
    public void someTestPropPartialContains() throws IOException {
        int numOfEntities = 20;
        String collectionName = "cantaloupes";
        // create our test entities
        generateTestEntities(numOfEntities, collectionName);
        // Query where madeup = true (the last half) and the last quarter of entries
        QueryParameters params = new QueryParameters()
            .setQuery("where sometestprop contains 'test*'");
        Collection coll = this.app().collection(collectionName).get(params);
        // results should have madeup = true and ordinal 15-19
        assertEquals(10, coll.getResponse().getEntityCount());


    }

    /**
     * Test an exclusive AND query to ensure the correct results are returned
     *
     * @throws IOException
     */
    @Test
    public void queryAndExclusive() throws IOException {
        int numOfEntities = 20;
        String collectionName = "dates";

        generateTestEntities(numOfEntities, collectionName);

        //Query where madeup = true (the last half) and NOT the last quarter of entries
        QueryParameters params = new QueryParameters()
            .setQuery("select * where madeup = true AND NOT ordinal >= " + (numOfEntities - numOfEntities / 4));
        Collection coll = this.app().collection(collectionName).get(params);
        //results should have madeup = true and ordinal 10-14
        assertEquals(numOfEntities / 4, coll.getResponse().getEntityCount());
        // loop though entities that were returned, and test against the ordinals and values we are
        // expecting, starting with the last expected entity and decrementing
        int index = 14;
        while (coll.hasNext()) {
            Entity entity = coll.next();
            //ensure the 'madeup' property is set to true
            assertTrue(Boolean.parseBoolean(entity.get("madeup").toString()));
            //make sure the correct ordinal properties are returned
            assertEquals(index--, Long.parseLong(entity.get("ordinal").toString()));
        }
    }

    /**
     * Test an inclusive OR query to ensure the correct results are returned
     *
     * @throws IOException
     */
    @Test
    public void queryOrInclusive() throws IOException {
        int numOfEntities = 20;
        String collectionName = "elderberries";

        generateTestEntities(numOfEntities, collectionName);

        //Query where madeup = false (the first half) or the last quarter of entries
        QueryParameters params = new QueryParameters()
            .setQuery("select * where madeup = false OR ordinal >= " + (numOfEntities - numOfEntities / 4))
            .setLimit((numOfEntities));
        Collection coll = this.app().collection(collectionName).get(params);
        int index = numOfEntities - 1;
        int count = 0;
        int returnSize = coll.getResponse().getEntityCount();
        //loop through the returned results
        for (int i = 0; i < returnSize; i++, index--) {
            count++;
            Entity entity = coll.getResponse().getEntities().get(i);
            logger.info(String.valueOf(entity.get("ordinal")) + " " + String.valueOf(entity.get("madeup")));
            //if the entity is in the first half, the property "madeup" should be false
            if (index < numOfEntities / 2) {
                assertFalse(Boolean.parseBoolean(String.valueOf(entity.get("madeup"))));
            }
            //else if the entity is in the second half, the property "madeup" should be true
            else if (index >= (numOfEntities - numOfEntities / 4)) {
                assertTrue(Boolean.parseBoolean(String.valueOf(entity.get("madeup"))));
            }
            //test to ensure that the ordinal is in the first half (where "madeup = false")
            //OR that the ordinal is in the last quarter of the entity list (where "ordinal >=  (numOfEntities - numOfEntities / 4))")
            long ordinal = Long.parseLong(String.valueOf(entity.get("ordinal")));
            assertTrue(ordinal < (numOfEntities / 2) || ordinal >= (numOfEntities - numOfEntities / 4));
        }
        //results should have madeup = false or ordinal 0-9,15-19
        //A total of 15 entities should be returned
        assertEquals(3 * numOfEntities / 4, count);
    }

    /**
     * Test an exclusive OR query to ensure the correct results are returned
     *
     * @throws IOException
     */
    @Test
    public void queryOrExclusive() throws IOException {
        int numOfEntities = 30;
        String collectionName = "figs";

        generateTestEntities(numOfEntities, collectionName);

        //Query where the verb = 'go' (half) OR the last quarter by ordinal, but NOT where verb = 'go' AND the ordinal is in the last quarter
        QueryParameters params = new QueryParameters()
            .setQuery("select * where (verb = 'go' OR ordinal >= " + (numOfEntities - numOfEntities / 4) + ") AND NOT (verb = 'go' AND ordinal >= " + (numOfEntities - numOfEntities / 4) + ")")
            .setLimit((numOfEntities));
        Collection coll = this.app().collection(collectionName).get(params);

        int index = numOfEntities - 1;
        int count = 0;
        int returnSize = coll.getResponse().getEntityCount();
        for (int i = 0; i < returnSize; i++, index--) {
            count++;
            Entity entity = coll.getResponse().getEntities().get(i);
            long ordinal = Long.parseLong(String.valueOf(entity.get("ordinal")));
            logger.info(ordinal + " " + String.valueOf(entity.get("verb")));
            //if the entity is in the first three quarters, the property "verb" should be "go"
            if (ordinal < (numOfEntities - numOfEntities / 4)) {
                assertEquals("go", String.valueOf(entity.get("verb")));
            }
            //if the entity is in the last quarter, the property "verb" should be "stop"
            else if (ordinal >= (numOfEntities - numOfEntities / 4)) {
                assertEquals("stop", String.valueOf(entity.get("verb")));
            }
        }
        //results should be even ordinals in the first 3 quarters and odd ordinals from the last quarter
        //Should return 1 more than half the number of entities
        assertEquals(1 + numOfEntities / 2, count);
    }

    /**
     * Ensure limit is respected in queries
     * 1. Query all entities where "madeup = true"
     * 2. Limit the query to half of the number of entities
     * 3. Ensure the correct entities are returned
     *
     * @throws IOException
     */
    @Test
    public void queryWithAndPastLimit() throws IOException {
        int numValuesTested = 40;

        String collectionName = "grapes";
        generateTestEntities(numValuesTested, collectionName);
        //3. Query all entities where "madeup = true"
        String errorQuery = "select * where madeup = true";
        QueryParameters params = new QueryParameters()
            .setQuery(errorQuery)
            .setLimit(numValuesTested / 2);//4. Limit the query to half of the number of entities
        Collection coll = this.app().collection(collectionName).get(params);
        //5. Ensure the correct entities are returned
        assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount());
        while (coll.hasNext()) {
            assertTrue(Boolean.parseBoolean(coll.next().get("madeup").toString()));
        }
    }


    /**
     * Test negated query
     * 1. Query all entities where "NOT verb = 'go'"
     * 2. Limit the query to half of the number of entities
     * 3. Ensure the returned entities have "verb = 'stop'"
     *
     * @throws IOException
     */
    @Test
    public void queryNegated() throws IOException {
        int numValuesTested = 20;

        String collectionName = "huckleberries";
        generateTestEntities(numValuesTested, collectionName);
        //1. Query all entities where "NOT verb = 'go'"
        String query = "select * where not verb = 'go'";
        //2. Limit the query to half of the number of entities
        QueryParameters params = new QueryParameters().setQuery(query).setLimit(numValuesTested / 2);
        Collection coll = this.app().collection(collectionName).get(params);
        //3. Ensure the returned entities have "verb = 'stop'"
        assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount());
        while (coll.hasNext()) {
            assertEquals("stop", coll.next().get("verb").toString());
        }


    }

    /**
     * Ensure queries return a subset of entities in the correct order
     * 1. Query for a subset of the entities
     * 2. Validate that the correct entities are returned
     *
     * @throws Exception
     */
    @Test
    public void queryReturnCount() throws Exception {
        int numValuesTested = 20;

        String collectionName = "lemons";
        generateTestEntities(numValuesTested, collectionName);
        //1. Query for a subset of the entities
        String inCorrectQuery = "select * where ordinal >= " + (numValuesTested / 2) + " order by ordinal asc";
        QueryParameters params = new QueryParameters().setQuery(inCorrectQuery).setLimit(numValuesTested / 2);
        Collection coll = this.app().collection(collectionName).get(params);
        //2. Validate that the correct entities are returned
        assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount());

        List<Entity> entitiesReturned = coll.getResponse().getEntities();
        for (int i = 0; i < numValuesTested / 2; i++) {
            assertEquals(numValuesTested / 2 + i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString()));
        }

    }

    /**
     * Validate sort order with AND/OR query
     * 1. Use AND/OR query to retrieve entities
     * 2. Verify the order of results
     *
     * @throws Exception
     */
    @Test
    public void queryCheckAsc() throws Exception {
        int numOfEntities = 20;
        String collectionName = "melons";

        generateTestEntities(numOfEntities, collectionName);

        //2. Use AND/OR query to retrieve entities
        String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte  " + (numOfEntities / 2)
            + " or WhoHelpedYou eq 'Ruff' ORDER BY Ordinal asc";
        QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery).setLimit(numOfEntities / 2);
        Collection activities = this.app().collection(collectionName).get(params);

        //3. Verify the order of results
        assertEquals(numOfEntities / 2, activities.getResponse().getEntityCount());
        List<Entity> entitiesReturned = activities.getResponse().getEntities();
        for (int i = 0; i < numOfEntities / 2; i++) {
            assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString()));
        }
    }


    /**
     * Test a standard query
     * 1. Issue a query
     * 2. validate that a full page of (10) entities is returned
     *
     * @throws Exception
     */
    @Test
    public void queryReturnCheck() throws Exception {
        int numOfEntities = 20;
        String collectionName = "nectarines";

        generateTestEntities(numOfEntities, collectionName);

        //2. Issue a query
        String inquisitiveQuery = String.format("select * where ordinal >= 0 and ordinal <= %d or WhoHelpedYou = 'Ruff' ORDER BY created", numOfEntities);
        QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery);
        Collection coll = this.app().collection(collectionName).get(params);

        //3. validate that a full page of (10) entities is returned
        assertEquals(10, coll.getResponse().getEntityCount());
        List<Entity> entitiesReturned = coll.getResponse().getEntities();
        for (int i = 0; i < 10; i++) {
            assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString()));
        }
    }

    /**
     * Test a standard query using alphanumeric operators
     * 1. Issue a query using alphanumeric operators
     * 2. validate that a full page of (10) entities is returned
     *
     * @throws Exception
     */
    @Test
    public void queryReturnCheckWithShortHand() throws Exception {
        int numOfEntities = 10;
        String collectionName = "oranges";

        generateTestEntities(numOfEntities, collectionName);

        //2. Issue a query using alphanumeric operators
        String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte 2000 or WhoHelpedYou eq 'Ruff' ORDER BY created";
        QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery);
        Collection activities = this.app().collection(collectionName).get(params);

        //3. validate that a full page of (10) entities is returned
        assertEquals(10, activities.getResponse().getEntityCount());
        List<Entity> entitiesReturned = activities.getResponse().getEntities();
        for (int i = 0; i < 10; i++) {
            assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString()));
        }
    }

}
