/*
 * Copyright (c) 2010, Stanislav Muhametsin. All Rights Reserved.
 * Copyright (c) 2012, Paul Merlin. All Rights Reserved.
 *
 * Licensed  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.qi4j.test.indexing;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.qi4j.api.property.Property;
import org.qi4j.api.query.Query;
import org.qi4j.api.query.QueryBuilder;
import org.qi4j.api.value.ValueBuilder;
import org.qi4j.spi.query.IndexExporter;
import org.qi4j.test.indexing.model.Address;
import org.qi4j.test.indexing.model.Person;
import org.qi4j.test.indexing.model.Protocol;
import org.qi4j.test.indexing.model.QueryParam;
import org.qi4j.test.indexing.model.URL;

import static org.qi4j.api.query.QueryExpressions.contains;
import static org.qi4j.api.query.QueryExpressions.containsAll;
import static org.qi4j.api.query.QueryExpressions.eq;
import static org.qi4j.api.query.QueryExpressions.not;
import static org.qi4j.api.query.QueryExpressions.templateFor;
import static org.qi4j.test.indexing.NameableAssert.verifyUnorderedResults;

/**
 * Abstract satisfiedBy with tests for complex queries against Index/Query engines, ie. queries by "example values".
 */
public abstract class AbstractComplexQueryTest
    extends AbstractAnyQueryTest
{

    private static final String ANN = "Ann Doe";
    private static final String JOE = "Joe Doe";
    private static final String JACK = "Jack Doe";

    @Test
    public void showNetwork()
        throws IOException
    {
        IndexExporter indexerExporter = module.<IndexExporter>findService( IndexExporter.class ).get();
        indexerExporter.exportReadableToStream( System.out );
    }

    @Test
    public void script01()
    {
        ValueBuilder<Address> addressBuilder = this.module.newValueBuilder( Address.class );
        Address address = addressBuilder.prototype();
        address.line1().set( "Qi Street 4j" );
        address.line2().set( "Off main Java Street" );
        address.zipcode().set( "12345" );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Address> addressProp = templateFor( Person.class ).address();
        qb = qb.where( eq( addressProp, addressBuilder.newInstance() ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script01: " + query );

        verifyUnorderedResults( query, ANN );
    }

    @Test
    public void script02()
    {
        ValueBuilder<Address> addressBuilder = this.module.newValueBuilder( Address.class );
        Address address = addressBuilder.prototype();
        address.line1().set( "Qi Street 4j" );
        address.line2().set( "Off main Java Street" );
        address.zipcode().set( "12345" );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Address> addressProp = templateFor( Person.class ).address();
        qb = qb.where( not( eq( addressProp, addressBuilder.newInstance() ) ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script02: " + query );

        verifyUnorderedResults( query, JOE, JACK );
    }

    @Test
    public void script03()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( eq( paramsProp, queryParams ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script03: " + query );

        verifyUnorderedResults( query, JACK );
    }

    @Test
    public void script04()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        // Different order
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( eq( paramsProp, queryParams ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script04: " + query );

        verifyUnorderedResults( query );
    }

    @Test
    public void script05()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( not( eq( paramsProp, queryParams ) ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script05: " + query );

        verifyUnorderedResults( query, ANN, JOE );
    }

    @Test
    public void script06()
    {
        ValueBuilder<URL> urlBuilder = this.module.newValueBuilder( URL.class );
        ValueBuilder<Protocol> protocolBuilder = this.module.newValueBuilder( Protocol.class );
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );

        Protocol protocol = protocolBuilder.prototype();
        protocol.value().set( "http" );

        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        URL url = urlBuilder.prototype();
        url.protocol().set( protocolBuilder.newInstance() );
        url.queryParams().set( queryParams );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<URL> websiteProp = templateFor( Person.class ).personalWebsite();
        qb = qb.where( eq( websiteProp, urlBuilder.newInstance() ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script06: " + query );

        verifyUnorderedResults( query, JACK );
    }

    @Test
    public void script07()
    {
        ValueBuilder<URL> urlBuilder = this.module.newValueBuilder( URL.class );
        ValueBuilder<Protocol> protocolBuilder = this.module.newValueBuilder( Protocol.class );
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );

        Protocol protocol = protocolBuilder.prototype();
        protocol.value().set( "http" );

        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        URL url = urlBuilder.prototype();
        url.protocol().set( protocolBuilder.newInstance() );
        url.queryParams().set( queryParams );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<URL> websiteProp = templateFor( Person.class ).personalWebsite();
        qb = qb.where( not( eq( websiteProp, urlBuilder.newInstance() ) ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script07: " + query );

        verifyUnorderedResults( query, ANN, JOE );
    }

    @Test
    public void script08()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( contains( paramsProp, queryParamBuilder.newInstance() ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script08: " + query );
        verifyUnorderedResults( query, JACK );
    }

    @Test
    public void script09()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );

        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( not( contains( paramsProp, queryParamBuilder.newInstance() ) ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script09: " + query );
        verifyUnorderedResults( query, ANN, JOE );
    }

    @Test
    public void script10()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );

        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( containsAll( paramsProp, queryParams ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script10: " + query );
        verifyUnorderedResults( query, JACK );
    }

    @Test
    public void script11()
    {
        ValueBuilder<QueryParam> queryParamBuilder = this.module.newValueBuilder( QueryParam.class );

        List<QueryParam> queryParams = new ArrayList<>( 2 );
        QueryParam param = queryParamBuilder.prototype();
        param.name().set( "user" );
        param.value().set( "jackdoe" );
        queryParams.add( queryParamBuilder.newInstance() );

        queryParamBuilder = this.module.newValueBuilder( QueryParam.class );
        param = queryParamBuilder.prototype();
        param.name().set( "password" );
        param.value().set( "somepassword" );
        queryParams.add( queryParamBuilder.newInstance() );

        QueryBuilder<Person> qb = this.module.newQueryBuilder( Person.class );
        Property<Collection<QueryParam>> paramsProp = templateFor( Person.class ).personalWebsite().get().queryParams();
        qb = qb.where( not( containsAll( paramsProp, queryParams ) ) );
        Query<Person> query = unitOfWork.newQuery( qb );
        System.out.println( "*** script11: " + query );
        verifyUnorderedResults( query, ANN, JOE );
    }
}
