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

#ifndef QUICKSTEP_RELATIONAL_OPERATORS_CREATE_INDEX_OPERATOR_HPP_
#define QUICKSTEP_RELATIONAL_OPERATORS_CREATE_INDEX_OPERATOR_HPP_

#include <cstddef>
#include <string>

#include "catalog/CatalogRelation.hpp"
#include "relational_operators/RelationalOperator.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "utility/Macros.hpp"

#include "glog/logging.h"

#include "tmb/id_typedefs.h"

namespace tmb { class MessageBus; }

namespace quickstep {

class CatalogRelation;
class QueryContext;
class StorageManager;
class WorkOrderProtosContainer;
class WorkOrdersContainer;

/** \addtogroup RelationalOperators
 *  @{
 */

/**
 * @brief An operator which creates an index.
 **/
class CreateIndexOperator : public RelationalOperator {
 public:
  /**
   * @brief Constructor.
   *
   * @param query_id The ID of the query to which this operator belongs.
   * @param relation The relation to create index upon.
   * @param index_name The index to create.
   * @param index_description The index_description associated with this index.
   **/
  CreateIndexOperator(const std::size_t query_id,
                      CatalogRelation *relation,
                      const std::string &index_name,
                      IndexSubBlockDescription &&index_description)  // NOLINT(whitespace/operators)
      : RelationalOperator(query_id),
        relation_(DCHECK_NOTNULL(relation)),
        index_name_(index_name),
        index_description_(index_description) {}

  ~CreateIndexOperator() override {}

  OperatorType getOperatorType() const override {
    return kCreateIndex;
  }

  std::string getName() const override {
    return "CreateIndexOperator";
  }

  /**
   * @note No WorkOrder generated for this operator.
   **/
  bool getAllWorkOrders(WorkOrdersContainer *container,
                        QueryContext *query_context,
                        StorageManager *storage_manager,
                        const tmb::client_id scheduler_client_id,
                        tmb::MessageBus *bus) override;

  /**
   * @note no WorkOrder proto generated for this operator.
   **/
  bool getAllWorkOrderProtos(WorkOrderProtosContainer *container) override {
    return true;
  }

  void updateCatalogOnCompletion() override;

 private:
  CatalogRelation *relation_;
  const std::string index_name_;
  IndexSubBlockDescription index_description_;

  DISALLOW_COPY_AND_ASSIGN(CreateIndexOperator);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_RELATIONAL_OPERATORS_CREATE_INDEX_OPERATOR_HPP_
