/**
 * 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 static org.junit.Assert.assertEquals;

import java.util.HashSet;
import java.util.Set;

import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.apache.rya.api.RdfCloudTripleStoreConstants;
import org.apache.rya.api.client.Install.InstallConfiguration;
import org.apache.rya.api.client.RyaClient;
import org.apache.rya.api.client.mongo.MongoConnectionDetails;
import org.apache.rya.api.client.mongo.MongoRyaClientFactory;
import org.apache.rya.indexing.accumulo.ConfigUtils;
import org.apache.rya.mongodb.MongoDBRdfConfiguration;
import org.apache.rya.mongodb.MongoITBase;
import org.apache.rya.sail.config.RyaSailFactory;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.query.impl.MapBindingSet;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
import org.eclipse.rdf4j.sail.Sail;
import org.junit.Test;

public class MongoPCJIndexIT extends MongoITBase {
    private static final ValueFactory VF = SimpleValueFactory.getInstance();

    @Override
    protected void updateConfiguration(final MongoDBRdfConfiguration conf) {
        conf.setBoolean(ConfigUtils.USE_MONGO, true);
        conf.setBoolean(ConfigUtils.USE_PCJ, false);
    }

    @Test
    public void sparqlQuery_Test() throws Exception {
        // Setup a Rya Client.
        final MongoConnectionDetails connectionDetails = getConnectionDetails();
        final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient());
        final String pcjQuery = "SELECT ?name WHERE {"
        		+ " ?name <urn:likes> <urn:icecream> ."
        		+ " ?name <urn:hasEyeColor> <urn:blue> ."
        		+ " }";

        // Install an instance of Rya and load statements.
        ryaClient.getInstall().install(conf.getRyaInstanceName(), InstallConfiguration.builder()
                .setEnablePcjIndex(true)
                .build());
        ryaClient.getLoadStatements().loadStatements(conf.getRyaInstanceName(), getStatements());
        final String pcjId = ryaClient.getCreatePCJ().createPCJ(conf.getRyaInstanceName(), pcjQuery);
        ryaClient.getBatchUpdatePCJ().batchUpdate(conf.getRyaInstanceName(), pcjId);

        //purge contents of rya triples collection
        getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection(conf.getTriplesCollectionName()).drop();
        
        //run the query.  since the triples collection is gone, if the results match, they came from the PCJ index.
        conf.setBoolean(ConfigUtils.USE_PCJ, true);
        conf.setBoolean(ConfigUtils.USE_OPTIMAL_PCJ, true);
        conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, true);
        final Sail sail = RyaSailFactory.getInstance(conf);
        SailRepositoryConnection conn = new SailRepository(sail).getConnection();
        conn.begin();
        final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, pcjQuery);
        tupleQuery.setBinding(RdfCloudTripleStoreConfiguration.CONF_QUERYPLAN_FLAG, RdfCloudTripleStoreConstants.VALUE_FACTORY.createLiteral(true));
        final TupleQueryResult rez = tupleQuery.evaluate();
        final Set<BindingSet> results = new HashSet<>();
        while(rez.hasNext()) {
            final BindingSet bs = rez.next();
            results.add(bs);
        }
        
     // Verify the correct results were loaded into the PCJ table.
        final Set<BindingSet> expectedResults = new HashSet<>();

        MapBindingSet bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Alice"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Bob"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Charlie"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:David"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Eve"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Frank"));
        expectedResults.add(bs);

        assertEquals(6, results.size());
        assertEquals(expectedResults, results);
    }
    
    @Test
    public void sparqlQuery_Test_complex() throws Exception {
        // Setup a Rya Client.
        final MongoConnectionDetails connectionDetails = getConnectionDetails();
        final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient());
        final String pcjQuery = "SELECT ?name WHERE {"
        		+ " ?name <urn:likes> <urn:icecream> ."
        		+ " ?name <urn:hasEyeColor> <urn:blue> ."
        		+ " }";
        
        final String testQuery = 
        		  "SELECT ?name WHERE {"
        		+ " ?name <urn:hasHairColor> <urn:brown> ."
        		+ " ?name <urn:likes> <urn:icecream> ."
        		+ " ?name <urn:hasEyeColor> <urn:blue> ."
        		+ " }";

        // Install an instance of Rya and load statements.
        conf.setBoolean(ConfigUtils.USE_PCJ, true);
        conf.setBoolean(ConfigUtils.USE_OPTIMAL_PCJ, true);
        conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, true);
        ryaClient.getInstall().install(conf.getRyaInstanceName(), InstallConfiguration.builder()
                .setEnablePcjIndex(true)
                .build());
        ryaClient.getLoadStatements().loadStatements(conf.getRyaInstanceName(), getStatements());
        final String pcjId = ryaClient.getCreatePCJ().createPCJ(conf.getRyaInstanceName(), pcjQuery);
        ryaClient.getBatchUpdatePCJ().batchUpdate(conf.getRyaInstanceName(), pcjId);

        System.out.println("Triples: " + getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection(conf.getTriplesCollectionName()).count());
        System.out.println("PCJS: " + getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection("pcjs").count());
        
        //run the query.  since the triples collection is gone, if the results match, they came from the PCJ index.
        final Sail sail = RyaSailFactory.getInstance(conf);
        SailRepositoryConnection conn = new SailRepository(sail).getConnection();
        conn.begin();
        final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, testQuery);
        tupleQuery.setBinding(RdfCloudTripleStoreConfiguration.CONF_QUERYPLAN_FLAG, RdfCloudTripleStoreConstants.VALUE_FACTORY.createLiteral(true));
        final TupleQueryResult rez = tupleQuery.evaluate();

        final Set<BindingSet> results = new HashSet<>();
        while(rez.hasNext()) {
            final BindingSet bs = rez.next();
            results.add(bs);
        }
        
     // Verify the correct results were loaded into the PCJ table.
        final Set<BindingSet> expectedResults = new HashSet<>();

        MapBindingSet bs = new MapBindingSet();
        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:David"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Eve"));
        expectedResults.add(bs);

        bs = new MapBindingSet();
        bs.addBinding("name", VF.createIRI("urn:Frank"));
        expectedResults.add(bs);

        assertEquals(3, results.size());
        assertEquals(expectedResults, results);
    }
    
    private MongoConnectionDetails getConnectionDetails() {
        final java.util.Optional<char[]> password = conf.getMongoPassword() != null ?
                java.util.Optional.of(conf.getMongoPassword().toCharArray()) :
                    java.util.Optional.empty();

        return new MongoConnectionDetails(
                conf.getMongoHostname(),
                Integer.parseInt(conf.getMongoPort()),
                java.util.Optional.ofNullable(conf.getMongoUser()),
                password);
    }

    private Set<Statement> getStatements() throws Exception {
        final Set<Statement> statements = new HashSet<>();
        statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream")));
        
        statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:green")));
        statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:brown")));
        
        statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue")));
        statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown")));
        statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown")));
        statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown")));
        statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blonde")));
        statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blonde")));
        return statements;
    }
}