/**
 * 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_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_
#define QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_

#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

#include "expressions/table_generator/GeneratorFunctionHandle.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVector.hpp"
#include "types/containers/ColumnVectorsValueAccessor.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief Handle for the instantiated GenerateSeries function.
 */
class GenerateSeriesHandle : public GeneratorFunctionHandle {
 public:
  int getNumberOfOutputColumns() const override {
    return 1;
  }

  const std::string getOutputColumnName(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    // Use the function name as the column name.
    return getName();
  }

  const Type& getOutputColumnType(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    return type_;
  }

  std::size_t getEstimatedCardinality() const override {
    switch (type_.getTypeID()) {
      case TypeID::kInt: {
        return estimateCardinality<int>();
      }
      case TypeID::kLong: {
        return estimateCardinality<std::int64_t>();
      }
      case TypeID::kFloat: {
        return estimateCardinality<float>();
      }
      case TypeID::kDouble: {
        return estimateCardinality<double>();
      }
      default:
        LOG(FATAL) << "GenerateSeries cannot handle arguments with type "
                   << type_.getName();
    }
    return 0;
  }

  void populateColumns(ColumnVectorsValueAccessor *results) const override {
    DCHECK(results != nullptr);

    // Generate the output column.
    NativeColumnVector *result_vec;
    switch (type_.getTypeID()) {
      case TypeID::kInt: {
        result_vec = generateColumn<int>();
        break;
      }
      case TypeID::kLong: {
        result_vec = generateColumn<std::int64_t>();
        break;
      }
      case TypeID::kFloat: {
        result_vec = generateColumn<float>();
        break;
      }
      case TypeID::kDouble: {
        result_vec = generateColumn<double>();
        break;
      }
      default:
        // Should not reach here -- type checking should be done inside
        // GenerateSeries::createHandle() at query compile time.
        LOG(FATAL) << "GenerateSeries cannot handle arguments with type "
                   << type_.getName();
    }
    // Add the output column into the ColumnVectorsValueAccessor container.
    results->addColumn(result_vec);
  }

 private:
  /**
   * @brief Constructor. A GenerateSeriesHandle object should only be
   *        instantiated inside method GenerateSeries::createHandle().
   *
   * @param func_name The registered name of the GenerateSeries function.
   * @param orig_args The original constant arguments to this function
   * @param type The unified type for the arguments.
   * @param start The start value. Its type should equal unified_type.
   * @param end The end value. Its type should equal unified_type.
   * @param step The step size. Its type should equal unified_type.
   */
  GenerateSeriesHandle(const std::string &func_name,
                       const std::vector<TypedValue> &orig_args,
                       const Type &unified_type,
                       const TypedValue &start,
                       const TypedValue &end,
                       const TypedValue &step)
      : GeneratorFunctionHandle(func_name, orig_args),
        type_(unified_type),
        start_(start),
        end_(end),
        step_(step) {
  }

  template <typename T>
  NativeColumnVector* generateColumn() const {
    T start = start_.getLiteral<T>();
    T end = end_.getLiteral<T>();
    T step = step_.getLiteral<T>();

    DCHECK_NE(step, static_cast<T>(0));
    std::size_t length = static_cast<std::size_t>((end - start) / step + 1);
    DCHECK_GE(length, static_cast<std::size_t>(0));

    NativeColumnVector *result_vec = new NativeColumnVector(type_, length);
    T value = start;
    for (std::size_t i = 0; i < length; ++i) {
      result_vec->appendUntypedValue(&value);
      value += step;
    }
    return result_vec;
  }

  template <typename T>
  std::size_t estimateCardinality() const {
    T step = step_.getLiteral<T>();
    DCHECK_NE(step, static_cast<T>(0));
    return static_cast<std::size_t>(
        (end_.getLiteral<T>() - start_.getLiteral<T>()) / step + 1);
  }

  const Type &type_;
  const TypedValue start_;
  const TypedValue end_;
  const TypedValue step_;

  friend class GenerateSeries;

  DISALLOW_COPY_AND_ASSIGN(GenerateSeriesHandle);
};

/** @} */

}  // namespace quickstep

#endif /* QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_ */
