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

#include "types/operations/binary_operations/AddBinaryOperation.hpp"

#include <string>
#include <utility>

#include "types/DateOperatorOverloads.hpp"
#include "types/DateType.hpp"
#include "types/DatetimeIntervalType.hpp"
#include "types/DatetimeLit.hpp"
#include "types/DatetimeType.hpp"
#include "types/IntervalLit.hpp"
#include "types/Type.hpp"
#include "types/TypeErrors.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/YearMonthIntervalType.hpp"
#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
#include "utility/EqualsAnyConstant.hpp"

#include "glog/logging.h"

namespace quickstep {

bool AddBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
  switch (left.getTypeID()) {
    case kInt:  // Fall through.
    case kLong:
    case kFloat:
    case kDouble: {
      return (right.getSuperTypeID() == Type::kNumeric);
    }
    case kDate: {
      return (right.getTypeID() == kYearMonthInterval);
    }
    case kDatetime: {
      return (right.getTypeID() == kDatetimeInterval ||
              right.getTypeID() == kYearMonthInterval);
    }
    case kDatetimeInterval: {
      return (right.getTypeID() == kDatetime ||
              right.getTypeID() == kDatetimeInterval);
    }
    case kYearMonthInterval: {
      return (right.getTypeID() == kDate ||
              right.getTypeID() == kDatetime ||
              right.getTypeID() == kYearMonthInterval);
    }
    default:
      return false;
  }
}

const Type* AddBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
    return TypeFactory::GetUnifyingType(left, right);
  } else if ((left.getTypeID() == kDatetime && right.getTypeID() == kDatetimeInterval)  ||
             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetime)  ||
             (left.getTypeID() == kDatetime && right.getTypeID() == kYearMonthInterval) ||
             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDatetime)) {
    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
  } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval) ||
             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDate)) {
    return &(DateType::Instance(left.isNullable() || right.isNullable()));
  } else if (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) {
    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
  } else if (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval) {
    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
  } else {
    return nullptr;
  }
}

const Type* AddBinaryOperation::resultTypeForPartialArgumentTypes(const Type *left,
                                                                  const Type *right) const {
  if ((left == nullptr) && (right == nullptr)) {
    return nullptr;
  }

  if ((left != nullptr) && (right != nullptr)) {
    return resultTypeForArgumentTypes(*left, *right);
  }

  // Addition is commutative, so we just determine based on the known type,
  // left or right.
  const Type *known_type = (left != nullptr) ? left : right;
  switch (known_type->getTypeID()) {
    case kDouble:
      // Double has highest precedence of the numeric types.
      return &TypeFactory::GetType(kDouble, true);
    case kDatetime:
      // Datetime can be added with either interval type, and always yields
      // Datetime.
      return &TypeFactory::GetType(kDatetime, true);
    case kDate:
      // Date can be added with YearMonthInterval type only, and always yields
      // Date.
      return &TypeFactory::GetType(kDate, true);
    default:
      // Ambiguous or inapplicable.
      return nullptr;
  }
}

bool AddBinaryOperation::partialTypeSignatureIsPlausible(
    const Type *result_type,
    const Type *left_argument_type,
    const Type *right_argument_type) const {
  if ((left_argument_type == nullptr) && (right_argument_type == nullptr)) {
    if (result_type == nullptr) {
      return true;
    } else if (!result_type->isNullable()) {
      // Unknown arguments are assumed to be nullable, since they arise from
      // untyped NULL literals in the parser. Therefore, a non-nullable result
      // Type is not plausible with unknown arguments.
      return false;
    } else {
      return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(),
                                           kInt,
                                           kLong,
                                           kFloat,
                                           kDouble,
                                           kDate,
                                           kDatetime,
                                           kDatetimeInterval,
                                           kYearMonthInterval);
    }
  }

  if ((left_argument_type != nullptr) && (right_argument_type != nullptr)) {
    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
                                                                *right_argument_type);
    if (actual_result_type == nullptr) {
      // Both argument Types are known, but this operation is NOT applicable to
      // them. No matter what the result_type is, the signature is not
      // plausible.
      return false;
    } else if (result_type == nullptr) {
      return true;
    } else {
      return result_type->equals(*actual_result_type);
    }
  }

  // Addition is commutative, so we just determine based on the known type,
  // left or right.
  const Type *known_argument_type = (left_argument_type != nullptr)
                                    ? left_argument_type
                                    : right_argument_type;
  if (result_type == nullptr) {
    return QUICKSTEP_EQUALS_ANY_CONSTANT(known_argument_type->getTypeID(),
                                         kInt,
                                         kLong,
                                         kFloat,
                                         kDouble,
                                         kDate,
                                         kDatetime,
                                         kDatetimeInterval,
                                         kYearMonthInterval);
  }

  if (!result_type->isNullable()) {
    // One of the arguments is unknown, but it is nevertheless assumed
    // nullable, since unknown argument Types arise from untyped NULL literals
    // in the parser. Therefore, a non-nullable result Type is not plausible
    // with an unknown argument.
    return false;
  }

  switch (result_type->getTypeID()) {
    case kInt:
      return (known_argument_type->getTypeID() == kInt);
    case kLong:
      return QUICKSTEP_EQUALS_ANY_CONSTANT(
          known_argument_type->getTypeID(),
          kInt, kLong);
    case kFloat:
      return QUICKSTEP_EQUALS_ANY_CONSTANT(
          known_argument_type->getTypeID(),
          kInt, kFloat);
    case kDouble:
      return QUICKSTEP_EQUALS_ANY_CONSTANT(
          known_argument_type->getTypeID(),
          kInt, kLong, kFloat, kDouble);
    case kDate:
      return (known_argument_type->getTypeID() == kDate);
    case kDatetime:
      return QUICKSTEP_EQUALS_ANY_CONSTANT(
          known_argument_type->getTypeID(),
          kDatetime, kDatetimeInterval);
    case kDatetimeInterval:
      return (known_argument_type->getTypeID() == kDatetimeInterval);
    case kYearMonthInterval:
      return (known_argument_type->getTypeID() == kYearMonthInterval);
    default:
      return false;
  }
}

std::pair<const Type*, const Type*> AddBinaryOperation::pushDownTypeHint(
    const Type *result_type_hint) const {
  if (result_type_hint == nullptr) {
    return std::pair<const Type*, const Type*>(nullptr, nullptr);
  }

  switch (result_type_hint->getTypeID()) {
    case kInt:
    case kLong:
    case kFloat:
    case kDouble:
    case kDatetimeInterval:
    case kYearMonthInterval:
      // Hint the same as the result type. Note that, for numeric types, one of
      // the argument Types can be a less precise Type and still yield the
      // specified result Type (e.g. DoubleType + IntType = DoubleType). We
      // choose the highest-precision suitable Type (i.e. the same as the
      // result type) in such cases.
      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
    case kDate:
      // Hint is ambiguous: one argument should be a Date, other has to be
      // kYearMonthInterval, but order is not important.
      return std::pair<const Type*, const Type*>(nullptr, nullptr);
    case kDatetime:
      // Hint is ambiguous: one argument should be a Datetime, the other should
      // be one of the interval types, but either order is acceptable.
      // Fortunately, the 3 types in question have syntactically distinct
      // representations in the SQL parser, so their literals don't need
      // disambiguation anyway.
      return std::pair<const Type*, const Type*>(nullptr, nullptr);
    default:
      // Inapplicable.
      return std::pair<const Type*, const Type*>(nullptr, nullptr);
  }
}

TypedValue AddBinaryOperation::applyToChecked(const TypedValue &left,
                                              const Type &left_type,
                                              const TypedValue &right,
                                              const Type &right_type) const {
  switch (left_type.getTypeID()) {
    case kInt:
    case kLong:
    case kFloat:
    case kDouble: {
      switch (right_type.getTypeID()) {
        case kInt:
        case kLong:
        case kFloat:
        case kDouble:
          return applyToCheckedNumericHelper<AddFunctor>(left, left_type,
                                                         right, right_type);
        default:
          break;
      }
      break;
    }
    case kDate: {
      if (right_type.getTypeID() == kYearMonthInterval) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDate);
        }

        return TypedValue(left.getLiteral<DateLit>() + right.getLiteral<YearMonthIntervalLit>());
      }
      break;
    }
    case kDatetime: {
      if (right_type.getTypeID() == kDatetimeInterval) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetime);
        }

        return TypedValue(left.getLiteral<DatetimeLit>() + right.getLiteral<DatetimeIntervalLit>());
      } else if (right_type.getTypeID() == kYearMonthInterval) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetime);
        }

        return TypedValue(left.getLiteral<DatetimeLit>() + right.getLiteral<YearMonthIntervalLit>());
      }
      break;
    }
    case kDatetimeInterval: {
      if (right_type.getTypeID() == kDatetime) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetime);
        }

        return TypedValue(left.getLiteral<DatetimeIntervalLit>() + right.getLiteral<DatetimeLit>());
      } else if (right_type.getTypeID() == kDatetimeInterval) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetimeInterval);
        }

        return TypedValue(left.getLiteral<DatetimeIntervalLit>() + right.getLiteral<DatetimeIntervalLit>());
      }
      break;
    }
    case kYearMonthInterval: {
      if (right_type.getTypeID() == kDate) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetime);
        }

        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<DateLit>());
      } else if (right_type.getTypeID() == kDatetime) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kDatetime);
        }

        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<DatetimeLit>());
      } else if (right_type.getTypeID() == kYearMonthInterval) {
        if (left.isNull() || right.isNull()) {
          return TypedValue(kYearMonthInterval);
        }

        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<YearMonthIntervalLit>());
      }
      break;
    }
    default:
      break;
  }

  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
             << left_type.getName() << " and " << right_type.getName();
}

UncheckedBinaryOperator* AddBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
                                                                                 const Type &right) const {
  switch (left.getTypeID()) {
    case kInt:
    case kLong:
    case kFloat:
    case kDouble: {
      if (right.getSuperTypeID() == Type::kNumeric) {
        return makeNumericBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator>(left, right);
      }
      break;
    }
    case kDate: {
      if (right.getTypeID() == kYearMonthInterval) {
        return makeDateBinaryOperatorOuterHelper<
            AddArithmeticUncheckedBinaryOperator,
            DateType,
            DateLit,
            YearMonthIntervalLit>(left, right);
      }
      break;
    }
    case kDatetime: {
      if (right.getTypeID() == kDatetimeInterval) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 DatetimeType,
                                                 DatetimeLit, DatetimeIntervalLit>(left, right);
      } else if (right.getTypeID() == kYearMonthInterval) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 DatetimeType,
                                                 DatetimeLit, YearMonthIntervalLit>(left, right);
      }
      break;
    }
    case kDatetimeInterval: {
      if (right.getTypeID() == kDatetime) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 DatetimeType,
                                                 DatetimeIntervalLit, DatetimeLit>(left, right);
      } else if (right.getTypeID() == kDatetimeInterval) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 DatetimeIntervalType,
                                                 DatetimeIntervalLit, DatetimeIntervalLit>(left, right);
      }
      break;
    }
    case kYearMonthInterval: {
      if (right.getTypeID() == kDate) {
        return makeDateBinaryOperatorOuterHelper<
            AddArithmeticUncheckedBinaryOperator,
            DateType,
            YearMonthIntervalLit,
            DateLit>(left, right);
      } else if (right.getTypeID() == kDatetime) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 DatetimeType,
                                                 YearMonthIntervalLit, DatetimeLit>(left, right);
      } else if (right.getTypeID() == kYearMonthInterval) {
        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
                                                 YearMonthIntervalType,
                                                 YearMonthIntervalLit, YearMonthIntervalLit>(left, right);
      }
      break;
    }
    default:
      break;
  }

  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
}

}  // namespace quickstep
