/*
 * 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.rya.indexing.mongo;

import java.util.List;

import org.apache.rya.api.domain.RyaType;
import org.apache.rya.api.domain.RyaURI;
import org.apache.rya.indexing.entity.EntityIndexOptimizer;
import org.apache.rya.indexing.entity.model.Entity;
import org.apache.rya.indexing.entity.model.Property;
import org.apache.rya.indexing.entity.model.Type;
import org.apache.rya.indexing.entity.query.EntityQueryNode;
import org.apache.rya.indexing.entity.storage.EntityStorage;
import org.apache.rya.indexing.entity.storage.TypeStorage;
import org.apache.rya.mongodb.MongoITBase;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.MalformedQueryException;
import org.eclipse.rdf4j.query.algebra.QueryModelNode;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import org.eclipse.rdf4j.query.algebra.helpers.StatementPatternCollector;
import org.eclipse.rdf4j.query.parser.sparql.SPARQLParser;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.google.common.collect.ImmutableSet;

public class MongoEntityIndex2IT extends MongoITBase {
    private static final Type PERSON_TYPE =
            new Type(new RyaURI("urn:person"),
                ImmutableSet.<RyaURI>builder()
                    .add(new RyaURI("urn:name"))
                    .add(new RyaURI("urn:age"))
                    .add(new RyaURI("urn:eye"))
                    .build());
    private static final RyaURI RYA_PERSON_TYPE = new RyaURI("urn:person");

    private EntityIndexOptimizer optimizer;
    private EntityStorage entityStorage;

    @Before
    public void beforeClass() throws Exception {
        optimizer = new EntityIndexOptimizer();
        optimizer.setConf(conf);

        final TypeStorage typeStorage = optimizer.getTypeStorage();
        typeStorage.create(PERSON_TYPE);

        final Entity entity = Entity.builder()
                .setSubject(new RyaURI("urn:SSN:111-11-1111"))
                .setExplicitType(RYA_PERSON_TYPE)
                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:age"), new RyaType("25")))
                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:eye"), new RyaType("blue")))
                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:name"), new RyaType("bob")))
                .build();
        entityStorage = optimizer.getEntityStorage();
        entityStorage.create(entity);
    }

    @Test()
    public void queryIsFullEntity() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(query), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryIsPartEntity() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(query), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryIsPartEntityandExtra() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
            "}";

        final String expectedQuery = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryIsFullEntityWithExtra() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
            "}";

        final String expectedQuery = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryIsFullEntityWithOptional() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
                "  OPTIONAL{" +
                "    <urn:SSN:222-22-2222> <urn:age> ?age . " +
                "    <urn:SSN:222-22-2222> <urn:eye> ?eye . " +
                "    <urn:SSN:222-22-2222> <urn:name> ?name . " +
                " } . " +
            "}";

        final String expectedQuery = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryIsSplitEntityWithOptional() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "  OPTIONAL{" +
                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
                " } . " +
            "}";

        final String expectedQuery = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
        assertOptimizer(query, expected);
    }

    @Test()
    public void queryEntityInOptional() throws Exception {
        // A pattern that has two different subjects.
        final String query = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
                "  OPTIONAL{" +
                "    <urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
                " } . " +
            "}";

        final String expectedQuery = "SELECT * WHERE { " +
                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
            "}";

        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
        assertOptimizer(query, expected);
    }

    private static List<StatementPattern> getSPs(final String sparql) throws MalformedQueryException {
        final StatementPatternCollector spCollector = new StatementPatternCollector();
        new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(spCollector);
        return spCollector.getStatementPatterns();
    }

    private void assertOptimizer(final String query, final EntityQueryNode expected) throws Exception {
        final SPARQLParser parser = new SPARQLParser();
        final TupleExpr expr = parser.parseQuery(query, null).getTupleExpr();

        optimizer.optimize(expr, null, null);
        expr.visit(new EntityFetchingAsserterVisitor(expected));
    }

    private class EntityFetchingAsserterVisitor extends AbstractQueryModelVisitor<Exception> {
        private final EntityQueryNode expected;
        public EntityFetchingAsserterVisitor(final EntityQueryNode expected) {
            this.expected = expected;
        }
        @Override
        protected void meetNode(final QueryModelNode node) throws Exception {
            if(node instanceof EntityQueryNode) {
                Assert.assertEquals(expected, node);
            } else {
                super.meetNode(node);
            }
        }
    }
}

