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


import java.util.Iterator;
import java.util.NoSuchElementException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.usergrid.corepersistence.pipeline.read.ResultsPage;
import org.apache.usergrid.persistence.Results;

import com.google.common.base.Optional;

import rx.Observable;


/**
 * Our proxy to allow us to subscribe to observable results, then return them as an iterator.  A bridge for 2.0 -> 1.0
 * code.  This should not be used on any new code, and will eventually be deleted
 */
@Deprecated//Required for 1.0 compatibility
public abstract class ObservableQueryExecutor<T> implements QueryExecutor {


    private static final Logger logger = LoggerFactory.getLogger( ObservableQueryExecutor.class );

    private Results results;
    private Optional<String> cursor;
    private boolean complete;

    protected ObservableQueryExecutor(final Optional<String> startCursor){
        this.cursor = startCursor;
    }




    /**
     * Transform the results
     * @param resultsPage
     * @return
     */
    protected abstract Results createResults( final ResultsPage<T> resultsPage );


    /**
     * Build new results page from the cursor
     * @param cursor
     * @return
     */
    protected abstract Observable<ResultsPage<T>> buildNewResultsPage(final Optional<String>  cursor);



    /**
     * Legacy to transform our results page to a new results
     * @param resultsPage
     * @return
     */
    private Results createResultsInternal( final ResultsPage<T> resultsPage ) {


        final Results results = createResults( resultsPage );

        //add the cursor if our limit is the same
        if ( resultsPage.hasMoreResults() ) {
            final Optional<String> cursor = resultsPage.getResponseCursor().encodeAsString();

            if ( cursor.isPresent() ) {
                results.setCursor( cursor.get() );
            }
        }
        return results;
    }





    @Override
    public Iterator<Results> iterator() {
        return this;
    }


    @Override
    public boolean hasNext() {

        if ( !complete && results == null) {
            if(logger.isTraceEnabled()){
                logger.trace("Iterator not complete and there are results object is null, advancing");
            }
            advance();
        }

        return results != null;
    }


    @Override
    public Results next() {
        if ( !hasNext() ) {
            throw new NoSuchElementException( "No more results present" );
        }

        final Results next = results;

        results = null;

        next.setQueryExecutor( this );

        return next;
    }

    private void advance(){
         //map to our old results objects, return a default empty if required
        final Observable<Results>
            observable = buildNewResultsPage( cursor ).map( resultsPage -> createResultsInternal( resultsPage ) ).defaultIfEmpty(
            new Results() );

        if (logger.isTraceEnabled()) {
            logger.trace("Trying to load results page");
        }

        //take the first from our observable
        final Results resultsPage = observable.take(1).toBlocking().first();

        if (logger.isTraceEnabled()) {
            logger.trace("Results page loaded {}", resultsPage);
        }

        //set the results for the iterator
        this.results = resultsPage;

        //set the complete flag
        this.complete =  !resultsPage.hasCursor();

        //if not comlete, set our cursor for the next iteration
        if(!complete){
            this.cursor = Optional.of( results.getCursor());
        }else{
            this.cursor = Optional.absent();
        }
    }


}
