/**
 * 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.apex.malhar.lib.appdata.query;

import com.google.common.base.Preconditions;

import com.datatorrent.api.Component;
import com.datatorrent.api.Context.OperatorContext;

/**
 * The QueryManagerSynchronous is a simple container for a {@link QueryExecutor} and a {@link QueueManager}.
 * It encapsulates the functionality of enqueueing a query and returning a result synchronously.
 * <br/>
 * <br/>
 * <b>Note:</b> Use {@link #newInstance} to create an instance of query processor.
 * It reduces the boilerplate code with respect to generics.
 *
 * @param <QUERY_TYPE> The type of the query.
 * @param <META_QUERY> The type of any query meta data.
 * @param <QUEUE_CONTEXT> The type of any context information used by the queue.
 * @param <RESULT> The type of the result returned by the {@link QueryExecutor}.
 * @since 3.0.0
 */
public class QueryManagerSynchronous<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> implements Component<OperatorContext>
{
  /**
   * The {@link QueryExecutor} used to execute queries.
   */
  private QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryExecutor;
  /**
   * The {@link QueueManager} used to queue queries.
   */
  private QueueManager<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT> queryQueueManager;

  /**
   *
   * @param queryComputer
   */
  private QueryManagerSynchronous(QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryComputer)
  {
    setQueryExecutor(queryComputer);
    queryQueueManager = new SimpleQueueManager<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT>();
  }

  private QueryManagerSynchronous(QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryComputer,
      QueueManager<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT> queryQueueManager)
  {
    setQueryExecutor(queryComputer);
    setQueryQueueManager(queryQueueManager);
  }

  /**
   * A helper method to set a {@link QueryExecutor}.
   * @param queryExecutor The {@link QueryExecutor} to set on the {@link QueryManagerSynchronous}.
   */
  private void setQueryExecutor(QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryExecutor)
  {
    this.queryExecutor = Preconditions.checkNotNull(queryExecutor);
  }

  /**
   * A helper method to set a {@link QueueManager}.
   * @param queryQueueManager The {@link QueueManager} to set on the {@link QueryManagerSynchronous}.
   */
  private void setQueryQueueManager(QueueManager<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT> queryQueueManager)
  {
    this.queryQueueManager = Preconditions.checkNotNull(queryQueueManager);
  }

  /**
   * This method enqueues the given query with the corresponding meta data.
   * @param query The query to enqueue .
   * @param metaQuery Any additional query meta data required to execute the query.
   * @param queueContext The queue context information required to queue the query.
   * @return True if the query was successfully enqueued and false otherwise.
   */
  public boolean enqueue(QUERY_TYPE query, META_QUERY metaQuery, QUEUE_CONTEXT queueContext)
  {
    return queryQueueManager.enqueue(query, metaQuery, queueContext);
  }

  /**
   * This method returns a result for the next query in the queue for which there is a result. If
   * there are no more queries with results in the queue, then this method will return null.
   * @return The result for the next query in the queue for which there is a result.
   */
  public RESULT process()
  {
    RESULT result = null;

    do {
      QueryBundle<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT> queryBundle = queryQueueManager.dequeue();

      if (queryBundle == null) {
        return null;
      }

      result = queryExecutor.executeQuery(queryBundle.getQuery(), queryBundle.getMetaQuery(),
          queryBundle.getQueueContext());
    }
    while (result == null);

    return result;
  }

  /**
   * This method should be called from the {@link com.datatorrent.api.Operator#setup} method so that the
 QueryManagerSynchronous can correctly initialize its internal state.
   * @param context The operator context.
   */
  @Override
  public void setup(OperatorContext context)
  {
    queryQueueManager.setup(context);
  }

  /**
   * This method should be called from the {@link com.datatorrent.api.Operator#beginWindow} method so that the
 QueryManagerSynchronous can correctly initialize/reset its internal state at the beginning of each window.
   * @param windowId The windowId of the current window.
   */
  public void beginWindow(long windowId)
  {
    queryQueueManager.beginWindow(windowId);
  }

  /**
   * This method should be called from the {@link com.datatorrent.api.Operator#endWindow} method so that the
 QueryManagerSynchronous can correctly initialize/reset its internal state at the end of each window.
   */
  public void endWindow()
  {
    queryQueueManager.endWindow();
  }

  /**
   * This method should be called from the {@link com.datatorrent.api.Operator#teardown} method so that the
 QueryManagerSynchronous can correctly initialize its internal state.
   */
  @Override
  public void teardown()
  {
    queryQueueManager.teardown();
  }

  /**
   * Creates a new instance of a QueryManagerSynchronous.
   * @param <QUERY_TYPE> The type of the query.
   * @param <META_QUERY> The type of any meta data associated with the query.
   * @param <QUEUE_CONTEXT> The type of any additional meta data required to manage queueing the query.
   * @param <RESULT> The type of any query results.
   * @param queryExecutor The {@link QueryExecutor} the queryExecutor used to execute queries.
   * @return A new instance of QueryManagerSynchronous.
   */
  public static <QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> QueryManagerSynchronous<QUERY_TYPE, META_QUERY,
      QUEUE_CONTEXT, RESULT> newInstance(QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryExecutor)
  {
    return new QueryManagerSynchronous<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT>(queryExecutor);
  }

  /**
   * Creates a new instance of a QueryManagerSynchronous.
   * @param <QUERY_TYPE> The type of the query.
   * @param <META_QUERY> The type of any meta data associated with the query.
   * @param <QUEUE_CONTEXT> The type of any additional meta data required to manage queueing the query.
   * @param <RESULT> The type of any query results.
   * @param queryExecutor The {@link QueryExecutor} used to execute queries.
   * @param queryQueueManager The {@link QueueManager} used to queue queries.
   * @return A new instance of QueryManagerSynchronous.
   */
  public static <QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> QueryManagerSynchronous<QUERY_TYPE, META_QUERY,
      QUEUE_CONTEXT, RESULT> newInstance(QueryExecutor<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT> queryExecutor,
      QueueManager<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT> queryQueueManager)
  {
    return new QueryManagerSynchronous<QUERY_TYPE, META_QUERY, QUEUE_CONTEXT, RESULT>(queryExecutor,
      queryQueueManager);
  }
}
