/*
 * 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.
 */

#pragma once

#ifndef GEODE_QUERYSERVICE_H_
#define GEODE_QUERYSERVICE_H_

#include <string>
#include <memory>

#include "internal/geode_globals.hpp"
#include "ExceptionTypes.hpp"
#include "CqQuery.hpp"
#include "CqAttributes.hpp"
#include "CqServiceStatistics.hpp"

#include "Query.hpp"

/**
 * @file
 */

namespace apache {
namespace geode {
namespace client {

/**
 * @class QueryService QueryService.hpp
 * QueryService is the class obtained from a Cache.
 * A Query is created from a QueryService and executed on the server
 * returning a SelectResults which can be either a ResultSet or a StructSet.
 */
class APACHE_GEODE_EXPORT QueryService {
 public:
  typedef std::vector<std::shared_ptr<CqQuery>> query_container_type;

  /**
   * Get a new Query with the specified query string.
   *
   * @param querystr The query string with which to create a new Query.
   * @returns A smart pointer to the Query.
   */
  virtual std::shared_ptr<Query> newQuery(std::string querystr) = 0;

  /**
   * Constructs a new named continuous query, represented by an instance of
   * CqQuery. The CqQuery is not executed, however, until the execute method
   * is invoked on the CqQuery. The name of the query will be used
   * to identify this query in statistics archival.
   *
   * @param cqName the String name for this query
   * @param queryString the OQL query
   * @param cqAttributes the CqAttributes
   * @param isDurable true if the CQ is durable
   * @return the newly created CqQuery object
   * @throws CqExistsException if a CQ by this name already exists on this
   * client
   * @throws IllegalArgumentException if queryString is null, or cqAttr is
   * nullptr
   * @throws IllegalStateException if this method is called from a cache
   *         server
   * @throws QueryInvalidException if there is a syntax error in the query
   * @throws CqException if failed to create cq, failure during creating
   *         managing cq metadata info.
   * @throws CqInvalidException if the query doesnot meet the CQ constraints.
   *   E.g.: Query string should refer only one region, join not supported.
   *         The query must be a SELECT statement.
   *         DISTINCT queries are not supported.
   *         Projections are not supported.
   *         Only one iterator in the FROM clause is supported, and it must be a
   * region path.
   *         Bind parameters in the query are not supported for the initial
   * release.
   */
  virtual std::shared_ptr<CqQuery> newCq(
      std::string name, std::string querystr,
      const std::shared_ptr<CqAttributes>& cqAttr, bool isDurable = false) = 0;

  /**
   * @nativeclient
   * Constructs a new named continuous query, represented by an instance of
   * CqQuery. The CqQuery is not executed, however, until the execute method
   * is invoked on the CqQuery. The name of the query will be used
   * to identify this query in statistics archival.
   *
   * @param queryString the OQL query
   * @param cqAttributes the CqAttributes
   * @param isDurable true if the CQ is durable
   * @return the newly created CqQuery object
   * @throws CqExistsException if a CQ by this name already exists on this
   * client
   * @throws IllegalArgumentException if queryString is null, or cqAttr is
   * nullptr
   * @throws IllegalStateException if this method is called from a cache
   *         server
   * @throws QueryInvalidException if there is a syntax error in the query
   * @throws CqException if failed to create cq, failure during creating
   *         managing cq metadata info.
   * @throws CqInvalidException if the query doesnot meet the CQ constraints.
   *   E.g.: Query string should refer only one region, join not supported.
   *         The query must be a SELECT statement.
   *         DISTINCT queries are not supported.
   *         Projections are not supported.
   *         Only one iterator in the FROM clause is supported, and it must be a
   * region path.
   *         Bind parameters in the query are not supported for the initial
   * release.
   *
   * @endnativeclient
   */
  virtual std::shared_ptr<CqQuery> newCq(
      std::string querystr, const std::shared_ptr<CqAttributes>& cqAttr,
      bool isDurable = false) = 0;

  /**
   * Close all CQs, and release resources
   * associated with executing CQs.
   */
  virtual void closeCqs() = 0;

  /**
   * @nativeclient
   * Retrieve  all registered CQs
   * @endnativeclient
   */
  virtual query_container_type getCqs() const = 0;

  /**
   * Retrieve a CqQuery by name.
   * @return the CqQuery or nullptr if not found
   */
  virtual std::shared_ptr<CqQuery> getCq(const std::string& name) const = 0;

  /**
   * @nativeclient
   * Executes all the cqs on this client.
   * @endnativeclient
   */
  virtual void executeCqs() = 0;

  /**
   * Stops all the cqs on this client.
   */
  virtual void stopCqs() = 0;

  /**
   * @nativeclient
   * Get statistics information for all CQs
   * @return the CqServiceStatistics
   * @endnativeclient
   */
  virtual std::shared_ptr<CqServiceStatistics> getCqServiceStatistics()
      const = 0;

  /**
   * Gets all the durable CQs registered by this client.
   *
   * @return List of names of registered durable CQs, empty list if no durable
   * cqs.
   */
  virtual std::shared_ptr<CacheableArrayList> getAllDurableCqsFromServer()
      const = 0;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_QUERYSERVICE_H_
