// 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 <gtest/gtest.h>

#include <string>

#include "parquet/types.h"

namespace parquet {

TEST(TestTypeToString, PhysicalTypes) {
  ASSERT_STREQ("BOOLEAN", TypeToString(Type::BOOLEAN).c_str());
  ASSERT_STREQ("INT32", TypeToString(Type::INT32).c_str());
  ASSERT_STREQ("INT64", TypeToString(Type::INT64).c_str());
  ASSERT_STREQ("INT96", TypeToString(Type::INT96).c_str());
  ASSERT_STREQ("FLOAT", TypeToString(Type::FLOAT).c_str());
  ASSERT_STREQ("DOUBLE", TypeToString(Type::DOUBLE).c_str());
  ASSERT_STREQ("BYTE_ARRAY", TypeToString(Type::BYTE_ARRAY).c_str());
  ASSERT_STREQ("FIXED_LEN_BYTE_ARRAY", TypeToString(Type::FIXED_LEN_BYTE_ARRAY).c_str());
}

TEST(TestLogicalTypeToString, LogicalTypes) {
  ASSERT_STREQ("NONE", LogicalTypeToString(LogicalType::NONE).c_str());
  ASSERT_STREQ("UTF8", LogicalTypeToString(LogicalType::UTF8).c_str());
  ASSERT_STREQ("MAP_KEY_VALUE", LogicalTypeToString(LogicalType::MAP_KEY_VALUE).c_str());
  ASSERT_STREQ("LIST", LogicalTypeToString(LogicalType::LIST).c_str());
  ASSERT_STREQ("ENUM", LogicalTypeToString(LogicalType::ENUM).c_str());
  ASSERT_STREQ("DECIMAL", LogicalTypeToString(LogicalType::DECIMAL).c_str());
  ASSERT_STREQ("DATE", LogicalTypeToString(LogicalType::DATE).c_str());
  ASSERT_STREQ("TIME_MILLIS", LogicalTypeToString(LogicalType::TIME_MILLIS).c_str());
  ASSERT_STREQ("TIME_MICROS", LogicalTypeToString(LogicalType::TIME_MICROS).c_str());
  ASSERT_STREQ(
      "TIMESTAMP_MILLIS", LogicalTypeToString(LogicalType::TIMESTAMP_MILLIS).c_str());
  ASSERT_STREQ(
      "TIMESTAMP_MICROS", LogicalTypeToString(LogicalType::TIMESTAMP_MICROS).c_str());
  ASSERT_STREQ("UINT_8", LogicalTypeToString(LogicalType::UINT_8).c_str());
  ASSERT_STREQ("UINT_16", LogicalTypeToString(LogicalType::UINT_16).c_str());
  ASSERT_STREQ("UINT_32", LogicalTypeToString(LogicalType::UINT_32).c_str());
  ASSERT_STREQ("UINT_64", LogicalTypeToString(LogicalType::UINT_64).c_str());
  ASSERT_STREQ("INT_8", LogicalTypeToString(LogicalType::INT_8).c_str());
  ASSERT_STREQ("INT_16", LogicalTypeToString(LogicalType::INT_16).c_str());
  ASSERT_STREQ("INT_32", LogicalTypeToString(LogicalType::INT_32).c_str());
  ASSERT_STREQ("INT_64", LogicalTypeToString(LogicalType::INT_64).c_str());
  ASSERT_STREQ("JSON", LogicalTypeToString(LogicalType::JSON).c_str());
  ASSERT_STREQ("BSON", LogicalTypeToString(LogicalType::BSON).c_str());
  ASSERT_STREQ("INTERVAL", LogicalTypeToString(LogicalType::INTERVAL).c_str());
}

TEST(TypePrinter, StatisticsTypes) {
  std::string smin;
  std::string smax;
  int32_t int_min = 1024;
  int32_t int_max = 2048;
  smin = std::string(reinterpret_cast<char*>(&int_min), sizeof(int32_t));
  smax = std::string(reinterpret_cast<char*>(&int_max), sizeof(int32_t));
  ASSERT_STREQ("1024", FormatStatValue(Type::INT32, smin.c_str()).c_str());
  ASSERT_STREQ("2048", FormatStatValue(Type::INT32, smax.c_str()).c_str());

  int64_t int64_min = 10240000000000;
  int64_t int64_max = 20480000000000;
  smin = std::string(reinterpret_cast<char*>(&int64_min), sizeof(int64_t));
  smax = std::string(reinterpret_cast<char*>(&int64_max), sizeof(int64_t));
  ASSERT_STREQ("10240000000000", FormatStatValue(Type::INT64, smin.c_str()).c_str());
  ASSERT_STREQ("20480000000000", FormatStatValue(Type::INT64, smax.c_str()).c_str());

  float float_min = 1.024;
  float float_max = 2.048;
  smin = std::string(reinterpret_cast<char*>(&float_min), sizeof(float));
  smax = std::string(reinterpret_cast<char*>(&float_max), sizeof(float));
  ASSERT_STREQ("1.024", FormatStatValue(Type::FLOAT, smin.c_str()).c_str());
  ASSERT_STREQ("2.048", FormatStatValue(Type::FLOAT, smax.c_str()).c_str());

  double double_min = 1.0245;
  double double_max = 2.0489;
  smin = std::string(reinterpret_cast<char*>(&double_min), sizeof(double));
  smax = std::string(reinterpret_cast<char*>(&double_max), sizeof(double));
  ASSERT_STREQ("1.0245", FormatStatValue(Type::DOUBLE, smin.c_str()).c_str());
  ASSERT_STREQ("2.0489", FormatStatValue(Type::DOUBLE, smax.c_str()).c_str());

  Int96 Int96_min = {{1024, 2048, 4096}};
  Int96 Int96_max = {{2048, 4096, 8192}};
  smin = std::string(reinterpret_cast<char*>(&Int96_min), sizeof(Int96));
  smax = std::string(reinterpret_cast<char*>(&Int96_max), sizeof(Int96));
  ASSERT_STREQ("1024 2048 4096 ", FormatStatValue(Type::INT96, smin.c_str()).c_str());
  ASSERT_STREQ("2048 4096 8192 ", FormatStatValue(Type::INT96, smax.c_str()).c_str());

  smin = std::string("abcdef");
  smax = std::string("ijklmnop");
  ASSERT_STREQ("abcdef ", FormatStatValue(Type::BYTE_ARRAY, smin.c_str()).c_str());
  ASSERT_STREQ("ijklmnop ", FormatStatValue(Type::BYTE_ARRAY, smax.c_str()).c_str());

  smin = std::string("abcdefgh");
  smax = std::string("ijklmnop");
  ASSERT_STREQ(
      "abcdefgh ", FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smin.c_str()).c_str());
  ASSERT_STREQ(
      "ijklmnop ", FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smax.c_str()).c_str());
}

}  // namespace parquet
