/**
 * 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 __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include "parser/ParseLiteralValue.hpp"

#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "types/DatetimeIntervalType.hpp"
#include "types/DoubleType.hpp"
#include "types/IntType.hpp"
#include "types/LongType.hpp"
#include "types/NullType.hpp"
#include "types/Type.hpp"
#include "types/VarCharType.hpp"
#include "types/YearMonthIntervalType.hpp"
#include "utility/SqlError.hpp"

#include "glog/logging.h"

namespace quickstep {

TypedValue NullParseLiteralValue::concretize(
    const Type *type_hint,
    const Type **concretized_type) const {
  if (type_hint == nullptr) {
    *concretized_type = &NullType::InstanceNullable();
  } else {
    *concretized_type = &(type_hint->getNullableVersion());
  }
  return (*concretized_type)->makeNullValue();
}

NumericParseLiteralValue::NumericParseLiteralValue(const int line_number,
                                                   const int column_number,
                                                   const char *numstring)
    : ParseLiteralValue(line_number, column_number),
      numeric_string_(numstring) {
  float_like_ = (numeric_string_.find('.') != std::string::npos)
                || (numeric_string_.find('e') != std::string::npos)
                || (numeric_string_.find('E') != std::string::npos);

  if (!float_like_) {
    CHECK_EQ(1, std::sscanf(numeric_string_.c_str(), "%" SCNd64, &long_value_))
        << "Failed to parse int64_t from numeric string \""
        << numeric_string_ << "\n";
  }
}

void NumericParseLiteralValue::prependMinus() {
  std::string minused("-");
  minused.append(numeric_string_);
  numeric_string_ = std::move(minused);

  if (!float_like_) {
    long_value_ = -long_value_;
  }
}

TypedValue NumericParseLiteralValue::concretize(
    const Type *type_hint,
    const Type **concretized_type) const {
  TypedValue parsed_value;
  if ((type_hint != nullptr)
      && (type_hint->getSuperTypeID() == Type::kNumeric)
      && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) {
    *concretized_type = &(type_hint->getNonNullableVersion());
    return parsed_value;
  }

  if (float_like_) {
    *concretized_type = &DoubleType::InstanceNonNullable();
    CHECK((*concretized_type)->parseValueFromString(numeric_string_, &parsed_value))
        << "Failed to parse double from numeric string \""
        << numeric_string_ << "\"";
    return parsed_value;
  } else {
    if ((long_value_ >= std::numeric_limits<int>::min())
        && (long_value_ <= std::numeric_limits<int>::max())) {
      *concretized_type = &IntType::InstanceNonNullable();
      return TypedValue(static_cast<int>(long_value_));
    } else {
      *concretized_type = &LongType::InstanceNonNullable();
      return TypedValue(long_value_);
    }
  }
}

void NumericParseLiteralValue::getFieldStringItems(
    std::vector<std::string> *inline_field_names,
    std::vector<std::string> *inline_field_values,
    std::vector<std::string> *non_container_child_field_names,
    std::vector<const ParseTreeNode*> *non_container_child_fields,
    std::vector<std::string> *container_child_field_names,
    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
  inline_field_names->push_back("numeric_string");
  inline_field_values->push_back(numeric_string_);

  inline_field_names->push_back("float_like");
  inline_field_values->push_back(float_like_ ? "true" : "false");
}

bool StringParseLiteralValue::ParseAmbiguousInterval(
    ParseString *value,
    StringParseLiteralValue **output) {
  *output = new StringParseLiteralValue(value,
                                        nullptr);  // Initially no explicit type.

  // Try parsing as DatetimeInterval.
  (*output)->explicit_type_ = &DatetimeIntervalType::InstanceNonNullable();
  if ((*output)->tryExplicitTypeParse()) {
    return true;
  }

  // Try parsing as YearMonthInterval.
  (*output)->explicit_type_ = &YearMonthIntervalType::InstanceNonNullable();
  if ((*output)->tryExplicitTypeParse()) {
    return true;
  }

  delete *output;
  *output = nullptr;
  return false;
}

TypedValue StringParseLiteralValue::concretize(const Type *type_hint,
                                               const Type **concretized_type) const {
  if (explicit_type_ != nullptr) {
    if ((type_hint != nullptr) && (type_hint->isSafelyCoercibleFrom(*explicit_type_))) {
      *concretized_type = type_hint;
      return type_hint->coerceValue(explicit_parsed_value_, *explicit_type_);
    } else {
      *concretized_type = explicit_type_;
      return explicit_parsed_value_;
    }
  } else {
    TypedValue parsed_value;
    if ((type_hint != nullptr)
        && (type_hint->parseValueFromString(value_->value(), &parsed_value))) {
      *concretized_type = &(type_hint->getNonNullableVersion());
      return parsed_value;
    } else {
      *concretized_type = &VarCharType::InstanceNonNullable(value_->value().length());
      CHECK((*concretized_type)->parseValueFromString(value_->value(), &parsed_value));
      return parsed_value;
    }
  }
}

std::string StringParseLiteralValue::generateName() const {
  std::string name;
  if (explicit_type_ != nullptr) {
    name.append(explicit_type_->getName());
    name.push_back('(');
  }
  name.push_back('\'');
  name.append(value_->value());
  name.push_back('\'');
  if (explicit_type_ != nullptr) {
    name.push_back(')');
  }
  return name;
}

bool StringParseLiteralValue::tryExplicitTypeParse() {
  DCHECK(explicit_type_ != nullptr);
  return explicit_type_->parseValueFromString(value_->value(), &explicit_parsed_value_);
}

void StringParseLiteralValue::getFieldStringItems(
    std::vector<std::string> *inline_field_names,
    std::vector<std::string> *inline_field_values,
    std::vector<std::string> *non_container_child_field_names,
    std::vector<const ParseTreeNode*> *non_container_child_fields,
    std::vector<std::string> *container_child_field_names,
    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
  inline_field_names->push_back("value");
  inline_field_values->push_back(value_->value());

  if (explicit_type_ != nullptr) {
    inline_field_names->push_back("explicit_type");
    inline_field_values->push_back(explicit_type_->getName());
  }
}

}  // namespace quickstep
