/**
 * 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 <initializer_list>
#include <utility>

#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/operations/binary_operations/BinaryOperation.hpp"
#include "types/operations/binary_operations/SubtractBinaryOperation.hpp"
#include "types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp"

#include "gtest/gtest.h"

namespace quickstep {

TEST(SubtractBinaryOperationTest, ResultTypeForPartialArgumentTypesTest) {
  // If both argument types are unknown, the result is unknown.
  EXPECT_EQ(nullptr,
            SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
                nullptr, nullptr));

  // If one of the arguments is a Double, the result is Double (since it has
  // the highest precedence of the numeric types).
  const Type *result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      nullptr,
      &TypeFactory::GetType(kDouble, false));
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      nullptr,
      &TypeFactory::GetType(kDouble, true));
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kDouble, false),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kDouble, true),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type));

  // If the left argument is a Date, then the result should be a Date.
  result_type =
      SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
          &TypeFactory::GetType(kDate, false), nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDate, true).equals(*result_type));

  // If the left argument (the minuend) is an interval, then the subtrahend and
  // the result must also be the same kind of interval.
  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kDatetimeInterval, false),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDatetimeInterval, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kDatetimeInterval, true),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDatetimeInterval, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kYearMonthInterval, false),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kYearMonthInterval, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      &TypeFactory::GetType(kYearMonthInterval, true),
      nullptr);
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kYearMonthInterval, true).equals(*result_type));

  // If the right argument (the subtrahend) is a Datetime, then the minuend
  // must also be a Datetime and the result is an interval.
  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      nullptr,
      &TypeFactory::GetType(kDatetime, false));
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDatetimeInterval, true).equals(*result_type));

  result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
      nullptr,
      &TypeFactory::GetType(kDatetime, true));
  ASSERT_NE(result_type, nullptr);
  EXPECT_TRUE(TypeFactory::GetType(kDatetimeInterval, true).equals(*result_type));

  // Other argument types give ambiguous or inapplicable results.
  for (const TypeID left_type_id : {kInt, kLong, kFloat, kDatetime, kChar, kVarChar}) {
    const Type *left_type = TypeFactory::TypeRequiresLengthParameter(left_type_id)
                            ? &TypeFactory::GetType(left_type_id, 10, false)
                            : &TypeFactory::GetType(left_type_id, false);
    EXPECT_EQ(nullptr,
              SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
                  left_type,
                  nullptr));
    EXPECT_EQ(nullptr,
              SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
                  &left_type->getNullableVersion(),
                  nullptr));
  }

  for (const TypeID right_type_id
       : {kInt, kLong, kFloat, kDatetimeInterval, kYearMonthInterval, kChar, kVarChar}) {
    const Type *right_type = TypeFactory::TypeRequiresLengthParameter(right_type_id)
                             ? &TypeFactory::GetType(right_type_id, 10, false)
                             : &TypeFactory::GetType(right_type_id, false);
    EXPECT_EQ(nullptr,
              SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
                  nullptr,
                  right_type));
    EXPECT_EQ(nullptr,
              SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes(
                  nullptr,
                  &right_type->getNullableVersion()));
  }
}

TEST(SubtractBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) {
  // --------------------------------------------------------------------------
  // All 3 Types unknown.
  EXPECT_TRUE(SubtractBinaryOperation::Instance().partialTypeSignatureIsPlausible(
      nullptr, nullptr, nullptr));

  // --------------------------------------------------------------------------
  // Result type known, both argument types unknown.
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndUnknownArguments(
      SubtractBinaryOperation::Instance(),
      {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval});

  // --------------------------------------------------------------------------
  // Result type unknown, one argument type known.
  BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument(
      SubtractBinaryOperation::Instance(),
      {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval},
      true,
      false);

  BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument(
      SubtractBinaryOperation::Instance(),
      {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval},
      false,
      true);

  // --------------------------------------------------------------------------
  // Result type and left argument type known.
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kInt, {kInt}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kLong, {kInt, kLong}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kFloat, {kInt, kFloat}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kDate, {kDate}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kDatetime, {kDatetime}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(),
      kDatetimeInterval, {kDatetime, kDatetimeInterval}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kYearMonthInterval, {kYearMonthInterval}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kChar, {}, true, false);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kVarChar, {}, true, false);

  // --------------------------------------------------------------------------
  // Result type and right argument type known.
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kInt, {kInt}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kLong, {kInt, kLong}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kFloat, {kInt, kFloat}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(),
      kDatetime, {kDatetimeInterval, kYearMonthInterval}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(),
      kDatetimeInterval, {kDatetime, kDatetimeInterval}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kYearMonthInterval, {kYearMonthInterval}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kChar, {}, false, true);
  BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument(
      SubtractBinaryOperation::Instance(), kVarChar, {}, false, true);
}

TEST(SubtractBinaryOperationTest, PushDownTypeHintTest) {
  const Type *result_type = nullptr;
  std::pair<const Type*, const Type*> hints
      = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  EXPECT_EQ(nullptr, hints.first);
  EXPECT_EQ(nullptr, hints.second);

  for (const TypeID type_id
       : {kInt, kLong, kFloat, kDouble, kYearMonthInterval}) {
    result_type = &TypeFactory::GetType(type_id, false);
    hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
    ASSERT_NE(hints.first, nullptr);
    ASSERT_NE(hints.second, nullptr);
    EXPECT_TRUE(result_type->equals(*hints.first));
    EXPECT_TRUE(result_type->equals(*hints.second));

    result_type = &TypeFactory::GetType(type_id, true);
    hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
    ASSERT_NE(hints.first, nullptr);
    ASSERT_NE(hints.second, nullptr);
    EXPECT_TRUE(result_type->equals(*hints.first));
    EXPECT_TRUE(result_type->equals(*hints.second));
  }

  result_type = &TypeFactory::GetType(kDate, false);
  hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  ASSERT_NE(hints.first, nullptr);
  EXPECT_TRUE(result_type->equals(*hints.first));
  EXPECT_EQ(&TypeFactory::GetType(kYearMonthInterval, true), hints.second);

  // A hint of Datetime means the left argument should be Datetime and the
  // right could be either interval type.
  result_type = &TypeFactory::GetType(kDatetime, false);
  hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  ASSERT_NE(hints.first, nullptr);
  EXPECT_TRUE(result_type->equals(*hints.first));
  EXPECT_EQ(nullptr, hints.second);

  result_type = &TypeFactory::GetType(kDatetime, true);
  hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  ASSERT_NE(hints.first, nullptr);
  EXPECT_TRUE(result_type->equals(*hints.first));
  EXPECT_EQ(nullptr, hints.second);

  // A hint of DatetimeInterval is ambiguous, because the arguments could be
  // a pair of DateTimes or a pair of DatetimeIntervals.
  result_type = &TypeFactory::GetType(kDatetimeInterval, false);
  hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  EXPECT_EQ(nullptr, hints.first);
  EXPECT_EQ(nullptr, hints.second);

  result_type = &TypeFactory::GetType(kDatetimeInterval, true);
  hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
  EXPECT_EQ(nullptr, hints.first);
  EXPECT_EQ(nullptr, hints.second);

  for (const TypeID string_type_id : {kChar, kVarChar}) {
    result_type = &TypeFactory::GetType(string_type_id, 10, false);
    hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
    EXPECT_EQ(nullptr, hints.first);
    EXPECT_EQ(nullptr, hints.second);

    result_type = &TypeFactory::GetType(string_type_id, 10, true);
    hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type);
    EXPECT_EQ(nullptr, hints.first);
    EXPECT_EQ(nullptr, hints.second);
  }
}

}  // namespace quickstep
