/**
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *   University of Wisconsin—Madison.
 *   Copyright 2016 Pivotal Software, Inc.
 *
 *   Licensed 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_HPP_
#define QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HPP_

#include <string>
#include <vector>

#include "expressions/table_generator/GenerateSeriesHandle.hpp"
#include "expressions/table_generator/GeneratorFunction.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
#include "types/operations/comparisons/GreaterComparison.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

class GeneratorFunctionHandle;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief GeneratorFunction that generates a series of values, from a start
 *        value to a stop value with a step size.
 */
class GenerateSeries : public GeneratorFunction {
 public:
  /**
   * @brief Singleton instance of the GenerateSeries class.
   * @return A const reference to the singleton instance of the GenerateSeries
   *         class.
   */
  static const GenerateSeries& Instance() {
    static GenerateSeries instance;
    return instance;
  }

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

  const std::string getSyntax() const override {
    return getName() + "(<start>, <end>[, <step>])";
  }

  GeneratorFunctionHandle* createHandle(
      const std::vector<TypedValue> &arguments) const override {
    // Checks arguments and create the function handle for generate_series.

    // Arguments should have the pattern (start, end) or (start, end, step).
    int arg_size = arguments.size();
    if (arg_size != 2 && arg_size != 3) {
      throw GeneratorFunctionInvalidArguments("Invalid number of arguments");
    }

    std::vector<const Type*> arg_types;
    for (const TypedValue &arg : arguments) {
      if (TypeFactory::TypeRequiresLengthParameter(arg.getTypeID())) {
        throw GeneratorFunctionInvalidArguments("Invalid argument types");
      }
      arg_types.emplace_back(&TypeFactory::GetType(arg.getTypeID()));
    }

    // Get the unified type of all arguments.
    const Type *unified_type = arg_types[0];
    for (int i = 1; i < arg_size && unified_type != nullptr; ++i) {
      unified_type =
          TypeFactory::GetUnifyingType(*arg_types[i],
                                       *unified_type);
    }

    // Check if the unified type if applicable, then create the handle.
    if (unified_type != nullptr) {
      TypeID tid = unified_type->getTypeID();
      if (tid == TypeID::kInt
          || tid == TypeID::kLong
          || tid == TypeID::kFloat
          || tid == TypeID::kDouble) {
        return concretizeWithType(arg_types, arguments, *unified_type);
      }
    }
    throw GeneratorFunctionInvalidArguments("Invalid argument types");
    return nullptr;
  }

 protected:
  GenerateSeries() : GeneratorFunction() {
  }

 private:
  GeneratorFunctionHandle* concretizeWithType(
      const std::vector<const Type*> &arg_types,
      const std::vector<TypedValue> &args,
      const Type &type) const {
    DCHECK(args.size() == 2 || args.size() == 3);

    // Coerce all arguments to the unified type.
    TypedValue start = type.coerceValue(args[0], *arg_types[0]);
    TypedValue end = type.coerceValue(args[1], *arg_types[1]);
    TypedValue step =
        args.size() > 2 ? type.coerceValue(args[2], *arg_types[2])
                        : type.coerceValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt));

    // Check that step is not 0, and (end - start) / step is positive
    const GreaterComparison &gt_comparator = GreaterComparison::Instance();
    bool start_gt_end = gt_comparator.compareTypedValuesChecked(start, type, end, type);
    bool step_gt_0 = gt_comparator.compareTypedValuesChecked(
        step, type, TypedValue(0), TypeFactory::GetType(TypeID::kInt));
    bool step_lt_0 = gt_comparator.compareTypedValuesChecked(
        TypedValue(0), TypeFactory::GetType(TypeID::kInt), step, type);
    if ((!start_gt_end && step_lt_0) || (start_gt_end && step_gt_0)) {
      throw GeneratorFunctionInvalidArguments("Invalid step width");
    }

    return new GenerateSeriesHandle(getName(), args, type, start, end, step);
  }

  DISALLOW_COPY_AND_ASSIGN(GenerateSeries);
};


/** @} */

}  // namespace quickstep

#endif /* QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HPP_ */
