/**
 * 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_PARSER_PARSE_SELECT_HPP_
#define QUICKSTEP_PARSER_PARSE_SELECT_HPP_

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

#include "parser/ParseGroupBy.hpp"
#include "parser/ParseHaving.hpp"
#include "parser/ParseLimit.hpp"
#include "parser/ParseOrderBy.hpp"
#include "parser/ParsePredicate.hpp"
#include "parser/ParseSelectionClause.hpp"
#include "parser/ParseTableReference.hpp"
#include "parser/ParseTreeNode.hpp"
#include "parser/ParseWindow.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrList.hpp"

#include "glog/logging.h"

namespace quickstep {

/**
 * @brief The parsed representation of a (sub-query) SELECT statement.
 **/
class ParseSelect : public ParseTreeNode {
 public:
  /**
   * @brief Constructor.
   * @note Takes ownership of all pointers.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param selection The parsed selection, which becomes owned by this
   *        ParseStatementSelect.
   * @param from_list The parsed list of table references in the FROM clause,
   *        which becomes owned by this ParseStatementSelect.
   * @param where_predicate An optional predicate representing the parsed
   *        WHERE clause (may be NULL if no predicate). Becomes owned by this
   *        ParseStatementSelect if non-NULL.
   * @param group_by Optional parsed GROUP BY clause. Becomes owned by this ParseStatementSelect.
   * @param having_predicate Optional parsed HAVING clause. Becomes owned by this ParseStatementSelect.
   * @param order_by Optional parsed ORDER BY clause. Becomes owned by this ParseStatementSelect.
   * @param limit Optional parsed LIMIT clause. Becomes owned by this ParseStatementSelect.
   **/
  ParseSelect(const int line_number,
              const int column_number,
              ParseSelectionClause *selection,
              PtrList<ParseTableReference> *from_list,
              ParsePredicate *where_predicate,
              ParseGroupBy *group_by,
              ParseHaving *having,
              ParseOrderBy *order_by,
              ParseLimit *limit,
              PtrList<ParseWindow> *window_list)
      : ParseTreeNode(line_number, column_number),
        selection_(selection),
        from_list_(from_list),
        where_predicate_(where_predicate),
        group_by_(group_by),
        having_(having),
        order_by_(order_by),
        limit_(limit),
        window_list_(window_list) {
  }

  ~ParseSelect() override {
  }

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

  /**
   * @brief Gets the selection.
   *
   * @return The selection.
   **/
  const ParseSelectionClause& selection() const {
    return *selection_;
  }

  /**
   * @brief Gets the FROM list.
   *
   * @return The list of table references in the FROM clause.
   **/
  const PtrList<ParseTableReference>& from_list() const {
    return *from_list_;
  }

  /**
   * @brief Determines whether this select statement has a WHERE predicate.
   *
   * @return Whether there is a WHERE predicate in this statement.
   **/
  bool hasWherePredicate() const {
    return where_predicate_.get() != nullptr;
  }

  /**
   * @brief Gets the WHERE predicate.
   * @warning Always call hasWherePredicate() first.
   *
   * @return The parsed WHERE predicate.
   **/
  const ParsePredicate& where_predicate() const {
    DCHECK(hasWherePredicate());
    return *where_predicate_;
  }

  /**
   * @brief Gets the parsed GROUP BY.
   *
   * @return The parsed GROUP BY.
   */
  const ParseGroupBy* group_by() const { return group_by_.get(); }

  /**
   * @brief Gets the parsed HAVING.
   *
   * @return The parsed HAVNING.
   */
  const ParseHaving* having() const { return having_.get(); }

  /**
   * @brief Gets the parsed ORDER BY.
   *
   * @return The parsed ORDER BY.
   */
  const ParseOrderBy* order_by() const { return order_by_.get(); }

  /**
   * @brief Gets the parsed LIMIT.
   *
   * @return The parsed LIMIT.
   */
  const ParseLimit* limit() const { return limit_.get(); }

  /**
   * @brief Gets the parsed WINDOW.
   *
   * @return The parsed WINDOW.
   */
  const PtrList<ParseWindow>* window_list() const { return window_list_.get(); }

 protected:
  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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    non_container_child_field_names->push_back("select_clause");
    non_container_child_fields->push_back(selection_.get());

    if (where_predicate_ != nullptr) {
      non_container_child_field_names->push_back("where_clause");
      non_container_child_fields->push_back(where_predicate_.get());
    }

    if (from_list_ != nullptr) {
      container_child_field_names->push_back("from_clause");
      container_child_fields->emplace_back();
      for (const ParseTableReference &from_item : *from_list_) {
        container_child_fields->back().push_back(&from_item);
      }
    }

    if (group_by_ != nullptr) {
      non_container_child_field_names->push_back("group_by");
      non_container_child_fields->push_back(group_by_.get());
    }

    if (having_ != nullptr) {
      non_container_child_field_names->push_back("having");
      non_container_child_fields->push_back(having_.get());
    }

    if (order_by_ != nullptr) {
      non_container_child_field_names->push_back("order_by");
      non_container_child_fields->push_back(order_by_.get());
    }

    if (limit_ != nullptr) {
      non_container_child_field_names->push_back("limit");
      non_container_child_fields->push_back(limit_.get());
    }

    if (window_list_ != nullptr) {
      container_child_field_names->push_back("window_list");
      container_child_fields->emplace_back();
      for (const ParseWindow &window : *window_list_) {
        container_child_fields->back().push_back(&window);
      }
    }
  }

 private:
  std::unique_ptr<ParseSelectionClause> selection_;
  std::unique_ptr<PtrList<ParseTableReference> > from_list_;
  std::unique_ptr<ParsePredicate> where_predicate_;
  std::unique_ptr<ParseGroupBy> group_by_;
  std::unique_ptr<ParseHaving> having_;
  std::unique_ptr<ParseOrderBy> order_by_;
  std::unique_ptr<ParseLimit> limit_;
  std::unique_ptr<PtrList<ParseWindow>> window_list_;

  DISALLOW_COPY_AND_ASSIGN(ParseSelect);
};

}  // namespace quickstep

#endif /* QUICKSTEP_PARSER_PARSESELECT_HPP_ */
