/**
 * 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_TYPES_TESTS_TYPE_TEST_COMMON_HPP_
#define QUICKSTEP_TYPES_TESTS_TYPE_TEST_COMMON_HPP_

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <limits>
#include <string>

#include "types/DoubleType.hpp"
#include "types/FloatType.hpp"
#include "types/IntType.hpp"
#include "types/LongType.hpp"
#include "types/NullType.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"

#include "gtest/gtest.h"

namespace quickstep {

namespace type_test {

/** \addtogroup Types
 *  @{
 */

/**
 * @brief Check that an implementation of Type::parseValueFromString() returns
 *        success and parses a string as expected.
 *
 * @param TypeT A type that is represented as a fixed-size literal.
 * @param expected_literal The literal value that the string should be parsed
 *        as.
 * @param value_string A string representation of expected_literal to attempt
 *        to parse.
 **/
template <typename TypeT>
void CheckSuccessfulParseLiteralValueFromString(
    const typename TypeT::cpptype expected_literal,
    const std::string &value_string) {
  const Type &type = TypeT::InstanceNonNullable();
  TypedValue value;
  ASSERT_TRUE(type.parseValueFromString(value_string, &value));
  EXPECT_EQ(expected_literal, value.getLiteral<typename TypeT::cpptype>());
}

/**
 * @brief Check that a given Type is coercible from a specified set of types,
 *        and not from others.
 *
 * @param target_type The Type to test the isCoercibleFrom() method for. This
 *        should be non-nullable, but this function will also test the nullable
 *        version.
 * @param expected_type A list of all the TypeIDs of Types that should be
 *        coercible to target_type.
 **/
void CheckIsCoercibleFrom(
    const Type &target_type,
    const std::initializer_list<TypeID> &expected_coercible) {
  const Type &target_type_nullable = target_type.getNullableVersion();

  for (const TypeID original_type_id : expected_coercible) {
    const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                ? TypeFactory::GetType(original_type_id, 10, false)
                                : TypeFactory::GetType(original_type_id, false);
    const Type &original_type_nullable = original_type.getNullableVersion();

    EXPECT_TRUE(target_type.isCoercibleFrom(original_type));
    // Can't coerce from nullable to non-nullable.
    EXPECT_FALSE(target_type.isCoercibleFrom(original_type_nullable));

    EXPECT_TRUE(target_type_nullable.isCoercibleFrom(original_type));
    EXPECT_TRUE(target_type_nullable.isCoercibleFrom(original_type_nullable));
  }

  // NullType is coercible to any nullable type.
  EXPECT_FALSE(target_type.isCoercibleFrom(TypeFactory::GetType(kNullType, true)));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(TypeFactory::GetType(kNullType, true)));

  // Can't coerce from other types.
  for (const TypeID original_type_id
       : {kInt, kLong, kFloat, kDouble, kChar, kVarChar,
          kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
    if (std::find(expected_coercible.begin(), expected_coercible.end(), original_type_id)
        == expected_coercible.end()) {
      const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                  ? TypeFactory::GetType(original_type_id, 10, false)
                                  : TypeFactory::GetType(original_type_id, false);
      const Type &original_type_nullable = original_type.getNullableVersion();

      EXPECT_FALSE(target_type.isCoercibleFrom(original_type));
      EXPECT_FALSE(target_type.isCoercibleFrom(original_type_nullable));
      EXPECT_FALSE(target_type_nullable.isCoercibleFrom(original_type));
      EXPECT_FALSE(target_type_nullable.isCoercibleFrom(original_type_nullable));
    }
  }
}

/**
 * @brief Check that an ASCII string type (i.e. CharType or VarCharType) is
 *        coercible from exactly the appropriate types (i.e. from any other
 *        ASCII string type).
 *
 * @param target_type_id The TypeID of the string Type to test.
 * @param target_length The length parameter of the string Type to test.
 **/
void CheckStringTypeIsCoercibleFrom(const TypeID target_type_id,
                                    const std::size_t target_length) {
  const Type &target_type = TypeFactory::GetType(target_type_id, target_length, false);
  const Type &target_type_nullable = TypeFactory::GetType(target_type_id, target_length, true);

  // Other string types to test against.
  const Type &shorter_char = TypeFactory::GetType(kChar, target_length - 1, false);
  const Type &shorter_char_nullable = TypeFactory::GetType(kChar, target_length - 1, true);
  const Type &same_char = TypeFactory::GetType(kChar, target_length, false);
  const Type &same_char_nullable = TypeFactory::GetType(kChar, target_length, true);
  const Type &longer_char = TypeFactory::GetType(kChar, target_length + 1, false);
  const Type &longer_char_nullable = TypeFactory::GetType(kChar, target_length + 1, true);

  const Type &shorter_varchar = TypeFactory::GetType(kVarChar, target_length - 1, false);
  const Type &shorter_varchar_nullable = TypeFactory::GetType(kVarChar, target_length - 1, true);
  const Type &same_varchar = TypeFactory::GetType(kVarChar, target_length, false);
  const Type &same_varchar_nullable = TypeFactory::GetType(kVarChar, target_length, true);
  const Type &longer_varchar = TypeFactory::GetType(kVarChar, target_length + 1, false);
  const Type &longer_varchar_nullable = TypeFactory::GetType(kVarChar, target_length + 1, true);

  // A non-nullable ASCII string type is coercible from any other non-nullable
  // ASCII string type.
  EXPECT_TRUE(target_type.isCoercibleFrom(shorter_char));
  EXPECT_FALSE(target_type.isCoercibleFrom(shorter_char_nullable));
  EXPECT_TRUE(target_type.isCoercibleFrom(same_char));
  EXPECT_FALSE(target_type.isCoercibleFrom(same_char_nullable));
  EXPECT_TRUE(target_type.isCoercibleFrom(longer_char));
  EXPECT_FALSE(target_type.isCoercibleFrom(longer_char_nullable));

  EXPECT_TRUE(target_type.isCoercibleFrom(shorter_varchar));
  EXPECT_FALSE(target_type.isCoercibleFrom(shorter_varchar_nullable));
  EXPECT_TRUE(target_type.isCoercibleFrom(same_varchar));
  EXPECT_FALSE(target_type.isCoercibleFrom(same_varchar_nullable));
  EXPECT_TRUE(target_type.isCoercibleFrom(longer_varchar));
  EXPECT_FALSE(target_type.isCoercibleFrom(longer_varchar_nullable));

  // A nullable ASCII string type is coercible from any other ASCII string
  // type.
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(shorter_char));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(shorter_char_nullable));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(same_char));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(same_char_nullable));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(longer_char));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(longer_char_nullable));

  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(shorter_varchar));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(shorter_varchar_nullable));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(same_varchar));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(same_varchar_nullable));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(longer_varchar));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(longer_varchar_nullable));

  // NullType can be coerced to any other nullable type.
  EXPECT_FALSE(target_type.isCoercibleFrom(TypeFactory::GetType(kNullType, true)));
  EXPECT_TRUE(target_type_nullable.isCoercibleFrom(TypeFactory::GetType(kNullType, true)));

  // Other types are not coercible to strings.
  for (const TypeID original_type_id
       : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
    const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                ? TypeFactory::GetType(original_type_id, 10, false)
                                : TypeFactory::GetType(original_type_id, false);
    const Type &original_type_nullable = original_type.getNullableVersion();

    EXPECT_FALSE(target_type.isCoercibleFrom(original_type));
    EXPECT_FALSE(target_type.isCoercibleFrom(original_type_nullable));
    EXPECT_FALSE(target_type_nullable.isCoercibleFrom(original_type));
    EXPECT_FALSE(target_type_nullable.isCoercibleFrom(original_type_nullable));
  }
}

/**
 * @brief Check that a given Type is safely coercible from a specified set of
 *        types, and not from others.
 *
 * @param target_type The Type to test the isSafelyCoercibleFrom() method for.
 *        This should be non-nullable, but this function will also test the
 *        nullable version.
 * @param expected_type A list of all the TypeIDs of Types that should be
 *        safely coercible to target_type.
 **/
void CheckIsSafelyCoercibleFrom(
    const Type &target_type,
    const std::initializer_list<TypeID> &expected_coercible) {
  const Type &target_type_nullable = target_type.getNullableVersion();

  for (const TypeID original_type_id : expected_coercible) {
    const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                ? TypeFactory::GetType(original_type_id, 10, false)
                                : TypeFactory::GetType(original_type_id, false);
    const Type &original_type_nullable = original_type.getNullableVersion();

    EXPECT_TRUE(target_type.isSafelyCoercibleFrom(original_type));
    // Can't coerce from nullable to non-nullable.
    EXPECT_FALSE(target_type.isSafelyCoercibleFrom(original_type_nullable));

    EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(original_type));
    EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(original_type_nullable));
  }

  // NullType is coercible to any nullable type.
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(TypeFactory::GetType(kNullType, true)));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(TypeFactory::GetType(kNullType, true)));

  // Can't coerce from other types.
  for (const TypeID original_type_id
       : {kInt, kLong, kFloat, kDouble, kChar, kVarChar,
          kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
    if (std::find(expected_coercible.begin(), expected_coercible.end(), original_type_id)
        == expected_coercible.end()) {
      const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                  ? TypeFactory::GetType(original_type_id, 10, false)
                                  : TypeFactory::GetType(original_type_id, false);
      const Type &original_type_nullable = original_type.getNullableVersion();

      EXPECT_FALSE(target_type.isSafelyCoercibleFrom(original_type));
      EXPECT_FALSE(target_type.isSafelyCoercibleFrom(original_type_nullable));
      EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(original_type));
      EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(original_type_nullable));
    }
  }
}

/**
 * @brief Check that an ASCII string type (i.e. CharType or VarCharType) is
 *        safely coercible from exactly the appropriate types (i.e. from any
 *        ASCII string type with the same or shorter length).
 *
 * @param target_type_id The TypeID of the string Type to test.
 * @param target_length The length parameter of the string Type to test.
 **/
void CheckStringTypeIsSafelyCoercibleFrom(const TypeID target_type_id,
                                          const std::size_t target_length) {
  const Type &target_type = TypeFactory::GetType(target_type_id, target_length, false);
  const Type &target_type_nullable = TypeFactory::GetType(target_type_id, target_length, true);

  // Other string types to test against.
  const Type &shorter_char = TypeFactory::GetType(kChar, target_length - 1, false);
  const Type &shorter_char_nullable = TypeFactory::GetType(kChar, target_length - 1, true);
  const Type &same_char = TypeFactory::GetType(kChar, target_length, false);
  const Type &same_char_nullable = TypeFactory::GetType(kChar, target_length, true);
  const Type &longer_char = TypeFactory::GetType(kChar, target_length + 1, false);
  const Type &longer_char_nullable = TypeFactory::GetType(kChar, target_length + 1, true);

  const Type &shorter_varchar = TypeFactory::GetType(kVarChar, target_length - 1, false);
  const Type &shorter_varchar_nullable = TypeFactory::GetType(kVarChar, target_length - 1, true);
  const Type &same_varchar = TypeFactory::GetType(kVarChar, target_length, false);
  const Type &same_varchar_nullable = TypeFactory::GetType(kVarChar, target_length, true);
  const Type &longer_varchar = TypeFactory::GetType(kVarChar, target_length + 1, false);
  const Type &longer_varchar_nullable = TypeFactory::GetType(kVarChar, target_length + 1, true);

  // A non-nullable ASCII string type is safely coercible from other
  // non-nullable ASCII string types with the same or lesser length.
  EXPECT_TRUE(target_type.isSafelyCoercibleFrom(shorter_char));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(shorter_char_nullable));
  EXPECT_TRUE(target_type.isSafelyCoercibleFrom(same_char));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(same_char_nullable));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(longer_char));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(longer_char_nullable));

  EXPECT_TRUE(target_type.isSafelyCoercibleFrom(shorter_varchar));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(shorter_varchar_nullable));
  EXPECT_TRUE(target_type.isSafelyCoercibleFrom(same_varchar));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(same_varchar_nullable));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(longer_varchar));
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(longer_varchar_nullable));

  // A nullable ASCII string type is safely coercible from other ASCII string
  // types with the same or lesser length.
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(shorter_char));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(shorter_char_nullable));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(same_char));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(same_char_nullable));
  EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(longer_char));
  EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(longer_char_nullable));

  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(shorter_varchar));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(shorter_varchar_nullable));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(same_varchar));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(same_varchar_nullable));
  EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(longer_varchar));
  EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(longer_varchar_nullable));

  // NullType can be safely coerced to any other nullable type.
  EXPECT_FALSE(target_type.isSafelyCoercibleFrom(TypeFactory::GetType(kNullType, true)));
  EXPECT_TRUE(target_type_nullable.isSafelyCoercibleFrom(TypeFactory::GetType(kNullType, true)));

  // Other types are not coercible to strings.
  for (const TypeID original_type_id
       : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
    const Type &original_type = TypeFactory::TypeRequiresLengthParameter(original_type_id)
                                ? TypeFactory::GetType(original_type_id, 10, false)
                                : TypeFactory::GetType(original_type_id, false);
    const Type &original_type_nullable = original_type.getNullableVersion();

    EXPECT_FALSE(target_type.isSafelyCoercibleFrom(original_type));
    EXPECT_FALSE(target_type.isSafelyCoercibleFrom(original_type_nullable));
    EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(original_type));
    EXPECT_FALSE(target_type_nullable.isSafelyCoercibleFrom(original_type_nullable));
  }
}

/**
 * @brief Check coercion between two types represented as in-line literal
 *        values.
 *
 * @param TargetType The Type to coerce to.
 * @param OriginalType The Type to coerce from.
 * @param literal The underlying literal value for the original value from
 *        OriginalType.
 **/
template <typename TargetType, typename OriginalType>
void CheckLiteralCoerce(const typename OriginalType::cpptype literal) {
  TypedValue value(literal);
  TypedValue coerced = TargetType::InstanceNonNullable().coerceValue(
      value,
      OriginalType::InstanceNonNullable());
  EXPECT_EQ(static_cast<typename TargetType::cpptype>(literal),
            coerced.getLiteral<typename TargetType::cpptype>());
}

/**
 * @brief Check coercion of a NULL value.
 *
 * @param TargetType The Type to coerce to.
 * @param OriginalType The Type to coerce from.
 **/
template <typename TargetType, typename OriginalType>
void CheckNullLiteralCoerce() {
  TypedValue value(OriginalType::InstanceNullable().makeNullValue());
  TypedValue coerced = TargetType::InstanceNullable().coerceValue(
      value,
      OriginalType::InstanceNullable());
  EXPECT_TRUE(coerced.isNull());
}

/**
 * @brief Run a battery of tests coercing values of various different numeric
 *        Types to a specified target Type.
 *
 * @param TargetType The Type to coerce to.
 **/
template <typename TargetType>
void CheckNumericCoerce() {
  CheckLiteralCoerce<TargetType, IntType>(0);
  CheckLiteralCoerce<TargetType, IntType>(123);
  CheckLiteralCoerce<TargetType, IntType>(-123);
  CheckLiteralCoerce<TargetType, IntType>(std::numeric_limits<int>::max());
  CheckLiteralCoerce<TargetType, IntType>(std::numeric_limits<int>::min());
  CheckNullLiteralCoerce<TargetType, IntType>();

  CheckLiteralCoerce<TargetType, LongType>(INT64_C(0));
  CheckLiteralCoerce<TargetType, LongType>(INT64_C(123));
  CheckLiteralCoerce<TargetType, LongType>(INT64_C(-123));
  CheckLiteralCoerce<TargetType, LongType>(std::numeric_limits<std::int64_t>::max());
  CheckLiteralCoerce<TargetType, LongType>(std::numeric_limits<std::int64_t>::min());
  CheckNullLiteralCoerce<TargetType, LongType>();

  CheckLiteralCoerce<TargetType, FloatType>(0.0f);
  CheckLiteralCoerce<TargetType, FloatType>(123.45f);
  CheckLiteralCoerce<TargetType, FloatType>(-123.45f);
  CheckLiteralCoerce<TargetType, FloatType>(std::numeric_limits<float>::max());
  CheckLiteralCoerce<TargetType, FloatType>(std::numeric_limits<float>::min());
  CheckNullLiteralCoerce<TargetType, FloatType>();

  CheckLiteralCoerce<TargetType, DoubleType>(0.0);
  CheckLiteralCoerce<TargetType, DoubleType>(123.45);
  CheckLiteralCoerce<TargetType, DoubleType>(-123.45);
  CheckLiteralCoerce<TargetType, DoubleType>(std::numeric_limits<double>::max());
  CheckLiteralCoerce<TargetType, DoubleType>(std::numeric_limits<double>::min());
  CheckNullLiteralCoerce<TargetType, DoubleType>();

  CheckNullLiteralCoerce<TargetType, NullType>();
}

/**
 * @brief Check coercion of CHAR literal values WITHOUT a null-terminator to
 *        a string Type.
 *
 * @param type_id The ID of the string type to coerce to.
 * @param literal The underlying string literal value to test coercion on.
 **/
void CheckStringCoerceFromCharWithoutNullTerminator(const TypeID type_id,
                                                    const std::string &literal) {
  const Type &target_type = TypeFactory::GetType(type_id, literal.size(), false);
  const Type &shorter_target_type = TypeFactory::GetType(type_id, literal.size() - 1, false);
  const Type &longer_target_type = TypeFactory::GetType(type_id, literal.size() + 10, false);

  const Type &char_type = TypeFactory::GetType(kChar, literal.size(), false);

  TypedValue char_value = char_type.makeValue(literal.c_str(), literal.size());
  TypedValue nonref_char_value = char_value;
  nonref_char_value.ensureNotReference();

  // Test coercion from a CHAR with exactly the right length (original value
  // has no null-terminator).
  TypedValue coerced = target_type.coerceValue(char_value, char_type);
  EXPECT_EQ(type_id, coerced.getTypeID());
  if (type_id == kChar) {
    // Still a reference to the same data.
    EXPECT_FALSE(coerced.ownsOutOfLineData());
    EXPECT_EQ(literal.size(), coerced.getDataSize());
    EXPECT_EQ(static_cast<const void*>(literal.c_str()), coerced.getDataPtr());
  } else {
    // Coercing to VARCHAR requires appending a null-terminator.
    EXPECT_TRUE(coerced.ownsOutOfLineData());
    EXPECT_EQ(literal.size() + 1, coerced.getDataSize());
    EXPECT_STREQ(literal.c_str(), static_cast<const char*>(coerced.getDataPtr()));
  }

  // Coercing from a literal makes a copy.
  TypedValue coerced_from_nonref = target_type.coerceValue(nonref_char_value, char_type);
  EXPECT_EQ(type_id, coerced_from_nonref.getTypeID());
  EXPECT_TRUE(coerced_from_nonref.ownsOutOfLineData());
  if (type_id == kChar) {
    ASSERT_EQ(literal.size(), coerced_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(coerced_from_nonref.getDataPtr()),
                              literal.size()));
  } else {
    EXPECT_EQ(literal.size() + 1, coerced_from_nonref.getDataSize());
    EXPECT_STREQ(literal.c_str(), static_cast<const char*>(coerced_from_nonref.getDataPtr()));
  }

  // Test shortening from a CHAR.
  TypedValue shortened = shorter_target_type.coerceValue(char_value, char_type);
  EXPECT_EQ(type_id, shortened.getTypeID());
  if (type_id == kChar) {
    // Still a reference to a shorter slice of the same data.
    EXPECT_FALSE(shortened.ownsOutOfLineData());
    EXPECT_EQ(literal.size() - 1, shortened.getDataSize());
    EXPECT_EQ(static_cast<const void*>(literal.c_str()), shortened.getDataPtr());
  } else {
    // End of string is trimmed and a null-terminator is appended.
    EXPECT_TRUE(shortened.ownsOutOfLineData());
    ASSERT_EQ(literal.size(), shortened.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened.getDataPtr()),
                              literal.size() - 1));
    EXPECT_EQ('\0', static_cast<const char*>(shortened.getDataPtr())[literal.size() - 1]);
  }

  // Again, coercing from a literal makes a copy.
  TypedValue shortened_from_nonref
      = shorter_target_type.coerceValue(nonref_char_value, char_type);
  EXPECT_EQ(type_id, shortened_from_nonref.getTypeID());
  EXPECT_TRUE(shortened_from_nonref.ownsOutOfLineData());
  if (type_id == kChar) {
    ASSERT_EQ(literal.size() - 1, shortened_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened_from_nonref.getDataPtr()),
                              literal.size() - 1));
  } else {
    EXPECT_EQ(literal.size(), shortened_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened_from_nonref.getDataPtr()),
                              literal.size() - 1));
    EXPECT_EQ('\0', static_cast<const char*>(
                        shortened_from_nonref.getDataPtr())[literal.size() - 1]);
  }

  // Test lengthening from a CHAR. This always needs to make a copy and append
  // a null-terminator.
  TypedValue lengthened
      = longer_target_type.coerceValue(char_value, char_type);
  EXPECT_EQ(type_id, lengthened.getTypeID());
  EXPECT_TRUE(lengthened.ownsOutOfLineData());
  EXPECT_EQ(literal.size() + 1, lengthened.getDataSize());
  EXPECT_STREQ(literal.c_str(), static_cast<const char*>(lengthened.getDataPtr()));

  // Same deal if the original is itself a literal.
  TypedValue lengthened_from_nonref
      = longer_target_type.coerceValue(nonref_char_value, char_type);
  EXPECT_EQ(type_id, lengthened_from_nonref.getTypeID());
  EXPECT_TRUE(lengthened_from_nonref.ownsOutOfLineData());
  EXPECT_EQ(literal.size() + 1, lengthened_from_nonref.getDataSize());
  EXPECT_STREQ(literal.c_str(),
               static_cast<const char*>(lengthened_from_nonref.getDataPtr()));
}

/**
 * @brief Check coercion of string literal values WITH a null-terminator to a
 *        string Type.
 *
 * @param type_id The ID of the string type to coerce to.
 * @param original_type_id The ID of the string type to coerce from.
 * @param literal The underlying string literal value to test coercion on.
 **/
void CheckStringCoerceWithNullTerminator(const TypeID type_id,
                                         const TypeID original_type_id,
                                         const std::string &literal) {
  const Type &target_type = TypeFactory::GetType(type_id, literal.size(), false);
  const Type &shorter_target_type = TypeFactory::GetType(type_id, literal.size() - 1, false);
  const Type &longer_target_type = TypeFactory::GetType(type_id, literal.size() + 10, false);

  const Type &original_type = TypeFactory::GetType(
      original_type_id,
      original_type_id == kChar ? literal.size() + 1
                                : literal.size(),
      false);
  TypedValue value = original_type.makeValue(literal.c_str(), literal.size() + 1);
  TypedValue nonref_value = value;
  nonref_value.ensureNotReference();

  // Should just be a reference to the original data.
  TypedValue coerced = target_type.coerceValue(value, original_type);
  EXPECT_EQ(type_id, coerced.getTypeID());
  EXPECT_FALSE(coerced.ownsOutOfLineData());
  EXPECT_EQ(type_id == kChar ? literal.size() : literal.size() + 1,
            coerced.getDataSize());
  EXPECT_EQ(static_cast<const void*>(literal.c_str()), coerced.getDataPtr());

  // Coercing from a literal makes a copy.
  TypedValue coerced_from_nonref  = target_type.coerceValue(nonref_value, original_type);
  EXPECT_EQ(type_id, coerced_from_nonref.getTypeID());
  EXPECT_TRUE(coerced_from_nonref.ownsOutOfLineData());
  if (type_id == kChar) {
    ASSERT_EQ(literal.size(), coerced_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(coerced_from_nonref.getDataPtr()),
                              literal.size()));
  } else {
    EXPECT_EQ(literal.size() + 1, coerced_from_nonref.getDataSize());
    EXPECT_STREQ(literal.c_str(), static_cast<const char*>(coerced_from_nonref.getDataPtr()));
  }

  // Test shortening.
  TypedValue shortened = shorter_target_type.coerceValue(value, original_type);
  EXPECT_EQ(type_id, shortened.getTypeID());
  if (type_id == kChar) {
    // Still a reference to a shorter slice of the same data.
    EXPECT_FALSE(shortened.ownsOutOfLineData());
    EXPECT_EQ(literal.size() - 1, shortened.getDataSize());
    EXPECT_EQ(static_cast<const void*>(literal.c_str()), shortened.getDataPtr());
  } else {
    // Shortening to a VARCHAR requires making a shorter copy with a
    // null-terminator.
    EXPECT_TRUE(shortened.ownsOutOfLineData());
    ASSERT_EQ(literal.size(), shortened.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened.getDataPtr()),
                              literal.size() - 1));
    EXPECT_EQ('\0', static_cast<const char*>(shortened.getDataPtr())[literal.size() - 1]);
  }

  // Again, coercing from a literal makes a copy.
  TypedValue shortened_from_nonref = shorter_target_type.coerceValue(nonref_value, original_type);
  EXPECT_EQ(type_id, shortened_from_nonref.getTypeID());
  EXPECT_TRUE(shortened_from_nonref.ownsOutOfLineData());
  if (type_id == kChar) {
    ASSERT_EQ(literal.size() - 1, shortened_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened_from_nonref.getDataPtr()),
                              literal.size() - 1));
  } else {
    EXPECT_EQ(literal.size(), shortened_from_nonref.getDataSize());
    EXPECT_EQ(0, std::strncmp(literal.c_str(),
                              static_cast<const char*>(shortened_from_nonref.getDataPtr()),
                              literal.size() - 1));
    EXPECT_EQ('\0', static_cast<const char*>(
                        shortened_from_nonref.getDataPtr())[literal.size() - 1]);
  }

  // Lengthening from a null-terminated original should stay as a reference to
  // the original data.
  TypedValue lengthened = longer_target_type.coerceValue(value, original_type);
  EXPECT_EQ(type_id, lengthened.getTypeID());
  EXPECT_FALSE(lengthened.ownsOutOfLineData());
  EXPECT_EQ(literal.size() + 1, lengthened.getDataSize());
  EXPECT_EQ(static_cast<const void*>(literal.c_str()), lengthened.getDataPtr());

  // If the original is a literal, a copy is made.
  TypedValue lengthened_from_nonref = longer_target_type.coerceValue(nonref_value, original_type);
  EXPECT_EQ(type_id, lengthened_from_nonref.getTypeID());
  EXPECT_TRUE(lengthened_from_nonref.ownsOutOfLineData());
  EXPECT_EQ(literal.size() + 1, lengthened_from_nonref.getDataSize());
  EXPECT_STREQ(literal.c_str(),
               static_cast<const char*>(lengthened_from_nonref.getDataPtr()));
}

/** @} */

}  // namespace type_test
}  // namespace quickstep

#endif  // QUICKSTEP_TYPES_TESTS_TYPE_TEST_COMMON_HPP_
