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

#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 {
    return true;
  }

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

  void updateCatalogOnCompletion() override {
    relation_->addIndex(index_name_, std::move(index_description_));
  }

 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_
