/**
 * 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_QUERY_OPTIMIZER_OPTIMIZER_TREE_HPP_
#define QUICKSTEP_QUERY_OPTIMIZER_OPTIMIZER_TREE_HPP_

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include "storage/StorageBlockLayout.pb.h"
#include "utility/Macros.hpp"
#include "utility/TreeStringSerializable.hpp"

#include "glog/logging.h"

namespace quickstep {
namespace optimizer {

/** \addtogroup QueryOptimizer
 *  @{
 */

/**
 * @brief Base class of OptimizerTree. This class is needed so that we may
 *        attach non-child type nodes to a tree in the string representation
 *        as long as the non-child type is a subclass of OptimizerTreeBase.
 *        For example, a Logical node may have a child tree node of an
 *        Expression type.
 */
class OptimizerTreeBase
    : public TreeStringSerializable<std::shared_ptr<const OptimizerTreeBase>> {
 public:
  typedef std::shared_ptr<const OptimizerTreeBase> OptimizerTreeBaseNodePtr;

  /**
   * @brief Destructor.
   */
  ~OptimizerTreeBase() override {}

 protected:
  /**
   * @brief Constructor.
   */
  OptimizerTreeBase() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(OptimizerTreeBase);
};

/**
 * @brief Base class for expressions, logical/physical trees.
 */
template <class NodeType>
class OptimizerTree : public OptimizerTreeBase {
 public:
  typedef std::shared_ptr<const NodeType> OptimizerTreeNodePtr;

  /**
   * @brief Destructor.
   */
  ~OptimizerTree() override {}

  /**
   * @brief Returns the child node list.
   *
   * @return A vector of children.
   */
  const std::vector<OptimizerTreeNodePtr>& children() const {
    return children_;
  }

  /**
   * @brief Returns the number of child nodes.
   *
   * @return The number of child nodes.
   */
  std::size_t getNumChildren() const { return children_.size(); }

  /**
   * @brief Creates a copy with the child nodes replaced by \p new_children.
   *
   * @param new_children The children to be substituted for the existing ones.
   * @return A copy with \p new_children as child nodes.
   */
  virtual OptimizerTreeNodePtr copyWithNewChildren(
      const std::vector<OptimizerTreeNodePtr> &new_children) const = 0;

 protected:
  /**
   * @brief Constructor.
   */
  OptimizerTree() {}

  /**
   * @brief Adds a new child node to this tree node->
   *
   * @param child The node to add as a new child.
   */
  void addChild(const OptimizerTreeNodePtr &child) {
    children_.push_back(child);
  }

 private:
  std::vector<OptimizerTreeNodePtr> children_;

  DISALLOW_COPY_AND_ASSIGN(OptimizerTree);
};

/**
 * @brief A helper class for printing Protobuf messages in a simple flat-format.
 * @details Holds key-value pairs of a proto message. Key values are added as strings.
 *          To use, create a representation and then add properties:
 *             auto foo = new OptimizerProtoRepresentation<OptimizerPtrType>();
 *             foo.addProperty("friendly_name", proto.GetExtension(ProtoType::friendly_name));
 */
template<class TreeNodeType>
class OptimizerProtoRepresentation : public OptimizerTreeBase {
  /**
   * @brief Inner class which represents key-value properties of the given proto.
   */
  class OptimizerProtoPropertyRepresentation : public OptimizerTreeBase {
   public:
    OptimizerProtoPropertyRepresentation(std::string key, std::string value)
        : key_(key), value_(value) {  }

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

    void getFieldStringItems(std::vector<std::string> *inline_field_names,
                             std::vector<std::string> *inline_field_values,
                             std::vector<std::string> *non_container_child_field_names,
                             std::vector<TreeNodeType> *non_container_child_fields,
                             std::vector<std::string> *container_child_field_names,
                             std::vector<std::vector<TreeNodeType>> *container_child_fields) const {
      inline_field_names->push_back(std::string("Property"));
      inline_field_values->push_back(key_);

      inline_field_names->push_back(std::string("Value"));
      inline_field_values->push_back(value_);
    }

   private:
    std::string key_;
    std::string value_;
  };  // class OptimizerProtoRepresentation

 public:
  OptimizerProtoRepresentation() : properties_() { }

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

  /**
   * @brief Add a key-value type property to this proto representation.
   * @details Internally, the instance creates another node to represent the
   *          given values.
   *
   * @param key A string key.
   * @param value A string value.
   */
  void addProperty(std::string key, std::string value) {
    std::shared_ptr<const OptimizerProtoPropertyRepresentation> property(
        new OptimizerProtoPropertyRepresentation(key, value));
    properties_.push_back(property);
  }

  /**
   * @brief Add a key-value type property to this proto representation.
   * @details Internally, the instance creates another node to represent the
   *          given values.
   *
   * @param key A string key.
   * @param value An int value which is converted into a string.
   */
  void addProperty(std::string key, int value) {
    std::shared_ptr<const OptimizerProtoPropertyRepresentation> property(
        new OptimizerProtoPropertyRepresentation(key, std::to_string(value)));
    properties_.push_back(property);
  }

  void getFieldStringItems(std::vector<std::string> *inline_field_names,
                           std::vector<std::string> *inline_field_values,
                           std::vector<std::string> *non_container_child_field_names,
                           std::vector<TreeNodeType> *non_container_child_fields,
                           std::vector<std::string> *container_child_field_names,
                           std::vector<std::vector<TreeNodeType>> *container_child_fields) const {
    for (auto property : properties_) {
      non_container_child_field_names->push_back("Property");
      non_container_child_fields->push_back(property);
    }
  }
  // A list of managed properties.
  std::vector<std::shared_ptr<const OptimizerProtoPropertyRepresentation> > properties_;
};

/**
 * @brief Returns an optimizer node representation of a LayoutDescription.
 *
 * @param description A valid StorageBlockLayoutDescription.
 * @return A caller-managed optimizer tree node of the proto message.
 */
template<class TreeNodeType>
OptimizerProtoRepresentation<TreeNodeType>* getOptimizerRepresentationForProto(
    const StorageBlockLayoutDescription *description) {
  if (description == nullptr) {
    return nullptr;
  }

  std::unique_ptr<OptimizerProtoRepresentation<TreeNodeType> >
      node(new OptimizerProtoRepresentation<TreeNodeType>());

  // Add properties based on the tuple storage block type.
  const ::quickstep::TupleStorageSubBlockDescription &storage_block_description
      = description->tuple_store_description();
  switch (storage_block_description.sub_block_type()) {
    case TupleStorageSubBlockDescription::SPLIT_ROW_STORE: {
      node->addProperty("blocktype", "split_rowstore");
      break;
    }
    case TupleStorageSubBlockDescription::BASIC_COLUMN_STORE: {
      node->addProperty("blocktype", "columnstore");
      node->addProperty("sort",
          storage_block_description.GetExtension(
              quickstep::BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
      break;
    }
    case TupleStorageSubBlockDescription::COMPRESSED_COLUMN_STORE: {
      node->addProperty("blocktype", "compressed_columnstore");
      node->addProperty("sort",
          storage_block_description.GetExtension(
              quickstep::CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
      for (int compressed_attribute = 0;
           compressed_attribute < storage_block_description.ExtensionSize(
               quickstep::CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id);
           ++compressed_attribute) {
        node->addProperty("compress",
            storage_block_description.GetExtension(
                quickstep::CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id,
                compressed_attribute));
      }
      break;
    }
    case TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE: {
      node->addProperty("blocktype", "compressed_packed_rowstore");
      for (int compressed_attribute = 0;
           compressed_attribute < storage_block_description.ExtensionSize(
               quickstep::CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id);
           ++compressed_attribute) {
        node->addProperty("compress",
            storage_block_description.GetExtension(
                quickstep::CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id,
                compressed_attribute));
      }
      break;
    }
    default: {
      LOG(WARNING) << "Unrecognized block type in protobuf message.";
      break;
    }
  }
  // Every case will specify a slots number.
  node->addProperty("slots", description->num_slots());
  return node.release();
}

/** @} */

}  // namespace optimizer
}  // namespace quickstep

#endif /* QUICKSTEP_QUERY_OPTIMIZER_OPTIMIZER_TREE_HPP_ */
