// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/expr/number_parser.h"

#include <ctype.h>
#include <math.h>
#include <stdlib.h>

#include "src/developer/debug/zxdb/expr/builtin_types.h"
#include "src/developer/debug/zxdb/expr/expr_token.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "third_party/double-conversion/double-conversion/double-conversion.h"

namespace zxdb {

namespace {

// Max values converted to a uint64_t.
constexpr uint64_t kSigned32Max = std::numeric_limits<int32_t>::max();
constexpr uint64_t kSigned64Max = std::numeric_limits<int64_t>::max();
constexpr uint64_t kUnsigned32Max = std::numeric_limits<uint32_t>::max();
constexpr uint64_t kUnsigned64Max = std::numeric_limits<uint64_t>::max();

// Absolute value of the smallest number that can be put in a signed 32-bit number. Be careful, the
// negative numbers hold one larger than the corresponding positive number which makes it hard to
// compute.
constexpr uint64_t kSigned32MaxAbsNeg = 0x80000000;
constexpr uint64_t kSigned64MaxAbsNeg = 0x8000000000000000ul;

// This hardcodes our current 64-bit type scheme where "long" and "long long" are both 64 bits, and
// "int" is 32. Note that we still support "long long" because it's surprising if you type "0x100ll"
// and don't get something called "long long" back.
//
// C++ has more rules about whether the input has a specific base (hex numbers prefer to be unsigned
// if possible), and the "l" suffix is particularly weird because it allows matching "unsigned long"
// while no other decimal numbers will match unsigned types without "u". Our requirements don't need
// all of these rules so keep things a bit simpler.
//
// See: https://en.cppreference.com/w/cpp/language/integer_literal
struct TypeLookup {
  const char* name;
  size_t byte_size;
  bool type_signed;

  // The largest positive value held by this type.
  uint64_t max_positive;

  // Absolute value of the most negative value held by this type. In the case of unsigned types,
  // this should hold the same value as the corresponding signed type. This allows "-23u" to specify
  // an unsigned version of the type that would normally hold "-23".
  uint64_t max_abs_negative;

  // Maximum suffix this type matches. If the number specifies "l" it will allow "long" or "long
  // long" but not int. Any lengths less than this will not match.
  IntegerSuffix::Length max_suffix;
} kTypeLookup[] = {
    // clang-format off
    // Name            bytes, signed max_positive    max_abs_negative,   max_suffix
    {"int",                4, true,  kSigned32Max,   kSigned32MaxAbsNeg, IntegerSuffix::Length::kInteger},
    {"unsigned",           4, false, kUnsigned32Max, kSigned32MaxAbsNeg, IntegerSuffix::Length::kInteger},
    {"long",               8, true,  kSigned64Max,   kSigned64MaxAbsNeg, IntegerSuffix::Length::kLong},
    {"unsigned long",      8, false, kUnsigned64Max, kSigned64MaxAbsNeg, IntegerSuffix::Length::kLong},
    {"long long",          8, true,  kSigned64Max,   kSigned64MaxAbsNeg, IntegerSuffix::Length::kLongLong},
    {"unsigned long long", 8, false, kUnsigned64Max, kSigned64MaxAbsNeg, IntegerSuffix::Length::kLongLong},
    // clang-format on
};

// Supports only base 2, 8, 10, and 16.
bool ValidForBase(IntegerPrefix::Base base, char c) {
  switch (base) {
    case IntegerPrefix::kBin:
      return c == '0' || c == '1';
    case IntegerPrefix::kOct:
      return c >= '0' && c <= '7';
    case IntegerPrefix::kDec:
      return c >= '0' && c <= '9';
    case IntegerPrefix::kHex:
      return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
  }
  return false;
}

// Returns the length of a <digits> sequence starting at the beginning of the input.
size_t GetDigitsLength(std::string_view input) {
  size_t result = 0;
  while (result < input.size() && isdigit(input[result]))
    result++;
  return result;
}

bool IsExponentCharacter(char c) { return c == 'e' || c == 'E'; }

bool IsSign(char c) { return c == '+' || c == '-'; }

}  // namespace

ErrOrValue StringToNumber(std::string_view str) {
  IntegerPrefix prefix = ExtractIntegerPrefix(&str);
  if (prefix.base == IntegerPrefix::kOct && prefix.octal_type == IntegerPrefix::OctalType::kC) {
    // Require "0o" prefixes for octal numbers instead of allowing C-style "0" prefixes. Octal
    // numbers are very unusual to be typed interactively in a debugger, and it's easier to
    // accidentally copy-and-paste a decimal number with a "0" at the beginning and get surprising
    // results. The "0o" format is used by Rust so we require it for clarity.
    return Err("Octal numbers must be prefixed with '0o'.");
  }

  auto suffix = ExtractIntegerSuffix(&str);
  if (suffix.has_error())
    return suffix.err();

  if (str.empty())
    return Err("Expected a number.");

  // Validate the characters in the number. This prevents strtoull from being too smart and trying
  // to handle prefixes itself.
  for (char c : str) {
    if (!ValidForBase(prefix.base, c))
      return Err("Invalid character in number.");
  }

  // strtoull doesn't take a const ending, but it doesn't modify the input.
  char* str_end = const_cast<char*>(str.end());
  char* parsed_end = str_end;

  // This will be the absolute value of the returned number.
  uint64_t abs_value = strtoull(str.data(), &parsed_end, static_cast<int>(prefix.base));

  // If strtoull stopped early it means it it hit an invalid character (shouldn't happen since we
  // validated above) or maybe the input was too long.
  if (parsed_end != str_end)
    return Err("Invalid number.");

  // Pick the smallest type that fits the data size as well as satisfies any suffixes.
  const TypeLookup* matched_type = nullptr;
  for (const auto& cur : kTypeLookup) {
    // Type must hold enough data.
    if (prefix.sign == IntegerPrefix::kNegative) {
      if (abs_value > cur.max_abs_negative)
        continue;
    } else {
      if (abs_value > cur.max_positive)
        continue;
    }

    if (static_cast<int>(cur.max_suffix) < static_cast<int>(suffix.value().length))
      continue;  // Requested length is larger.

    if (suffix.value().type_signed == IntegerSuffix::kUnsigned) {
      if (cur.type_signed)
        continue;  // Unsigned suffix requires unsigned type.
    } else if (prefix.sign == IntegerPrefix::kNegative && !cur.type_signed) {
      // Signed input requires a signed type unless a suffix overrode it which was checked above
      // ("-1u" should be unsigned).
      continue;
    }

    matched_type = &cur;
    break;
  }

  if (!matched_type) {
    // Anything not matched above will be an overflow. Put it into a unsigned 64-bit value and
    // tolerate the overflow.
    matched_type = &*(std::end(kTypeLookup) - 1);
  }

  int symbol_tag =
      matched_type->type_signed ? BaseType::kBaseTypeSigned : BaseType::kBaseTypeUnsigned;
  auto type =
      fxl::MakeRefCounted<BaseType>(symbol_tag, matched_type->byte_size, matched_type->name);

  uint64_t value = prefix.sign == IntegerPrefix::kNegative ? -abs_value : abs_value;

  // Construct the data. This assumes little-endian since it truncates or zero-fills off the right.
  std::vector<uint8_t> data(matched_type->byte_size);
  memcpy(&data[0], &value, matched_type->byte_size);

  return ExprValue(std::move(type), std::move(data));
}

IntegerPrefix ExtractIntegerPrefix(std::string_view* s) {
  IntegerPrefix prefix;
  if (s->empty())
    return prefix;  // Defaults OK for empty string.

  if ((*s)[0] == '-') {
    prefix.sign = IntegerPrefix::kNegative;

    // Allow whitespace between negative sign and the rest.
    size_t sign_len = 1;
    while (sign_len < s->size() && isspace((*s)[sign_len]))
      sign_len++;
    *s = s->substr(sign_len);
  }

  if (s->size() >= 2u && (*s)[0] == '0') {
    char second = (*s)[1];
    if (second == 'x' || second == 'X') {
      // Hex.
      *s = s->substr(2u);
      prefix.base = IntegerPrefix::kHex;
    } else if (second == 'b' || second == 'B') {
      // Binary.
      *s = s->substr(2u);
      prefix.base = IntegerPrefix::kBin;
    } else if (second == 'o' || second == 'O') {
      // Rust-style octal "0o".
      *s = s->substr(2u);
      prefix.base = IntegerPrefix::kOct;
      prefix.octal_type = IntegerPrefix::OctalType::kRust;
    } else {
      // Everything else beginning with a '0' is C-style octal. Note this requires >= 2 digits so
      // that "0" by itself is decimal.
      *s = s->substr(1u);
      prefix.base = IntegerPrefix::kOct;
      prefix.octal_type = IntegerPrefix::OctalType::kC;
    }
  }
  // Else case is decimal, doesn't need trimming, default is already correct.
  return prefix;
}

ErrOr<IntegerSuffix> ExtractIntegerSuffix(std::string_view* s) {
  IntegerSuffix suffix;

  // Check for any combination of "u" and either "l" or "ll". This works backwards to avoid two
  // passes since the suffix means the same in either order.
  bool have_unsigned = false;
  bool have_length = false;
  size_t suffix_begin = s->size();
  while (suffix_begin > 0) {
    char prev_char = (*s)[suffix_begin - 1];
    if (prev_char == 'U' || prev_char == 'u') {
      // Unsigned suffix.
      if (have_unsigned)
        return Err("Duplicate 'u' in number suffix.");
      have_unsigned = true;

      suffix.type_signed = IntegerSuffix::kUnsigned;
      suffix_begin--;
    } else if (prev_char == 'L' || prev_char == 'l') {
      // Suffix has an "l", disambiguate based on previous char.
      if (have_length)
        return Err("Duplicate 'l' or 'll' in number suffix.");
      have_length = true;

      // Technically C++ says "Ll" and "lL" aren't allowed, but we don't bother enforcing this.
      if (suffix_begin > 1 && ((*s)[suffix_begin - 2] == 'l' || (*s)[suffix_begin - 2] == 'L')) {
        // "ll" = Long long.
        suffix.length = IntegerSuffix::Length::kLongLong;
        suffix_begin -= 2;
      } else {
        // "l" by itself = Long.
        suffix.length = IntegerSuffix::Length::kLong;
        suffix_begin--;
      }
    } else {
      // Not a valid suffix number, stop.
      break;
    }
  }

  *s = s->substr(0, suffix_begin);
  return suffix;
}

// The floating-point format we expect is:
//
//   <float> := ( <significand> [<exponent>] [<suffix>] ) |
//              ( <digis> <exponent> [<suffix>] )
//
//   <significant> := ( <digits> "." <digits> ) |
//                    ( "." <digits> ) |
//                    ( <digits> "." )
//
//   <exponent> := ("e" | "E") [("+" | "-")] <digits>
//
//   <suffix> := "f" | "F" | "l" | "L"
//
// In other words, a floating point number must have either a "." or an "e", and a "." must have
// digits on at least one side of it.
//
// Rust requires that there be digits before a ".". This is important to disambiguate cases like
// "tuple.0" as being "tuple dot zero" from "tuple float-zero".
//
// TODO(bug 43220) Handle Rust-specific suffixes.
// TODO(bug 43222) Support C++17 hex floating point literals "0x342.1a"
size_t GetFloatTokenLength(ExprLanguage lang, std::string_view input) {
  std::string_view cur = input;

  // Digits before the dot.
  size_t before_dot = GetDigitsLength(cur);
  cur = cur.substr(before_dot);
  if (lang == ExprLanguage::kRust & before_dot == 0)
    return 0;

  // "."
  bool has_dot = false;
  if (!cur.empty() && cur[0] == '.') {
    has_dot = true;
    cur = cur.substr(1);
  }
  if (!before_dot && !has_dot)
    return 0;  // Must begin with digits or a dot to be a float.

  // Digits after the dot.
  size_t after_dot = GetDigitsLength(cur);
  cur = cur.substr(after_dot);
  if (has_dot && !before_dot && !after_dot)
    return 0;  // A dot must have digits on at least one side.

  // Optional exponent.
  bool has_exponent = false;
  if (!cur.empty() && IsExponentCharacter(cur[0])) {
    has_exponent = true;
    cur = cur.substr(1);

    if (!cur.empty() && IsSign(cur[0]))
      cur = cur.substr(1);  // Skip optional sign.

    size_t exponent = GetDigitsLength(cur);
    if (!exponent)
      return 0;  // Must have exponent digits to be a float.
    cur = cur.substr(exponent);
  }
  if (!has_dot && !has_exponent)
    return 0;  // Must have a dot or an exponend to be a float.

  // Consider all alphanumeric characters immediately following to be part of the token. This will
  // get any suffix characters but may get garbage also. The tokenizer isn't in charge of validating
  // floating point formatting, and something like "2.3hello" should be considered one invalid
  // floating-point token rather than a valid float followed by a valid identifier.
  while (!cur.empty() && isalnum(cur[0]))
    cur = cur.substr(1);

  return &cur[0] - &input[0];
}

FloatSuffix StripFloatSuffix(std::string_view* view) {
  if (view->empty())
    return FloatSuffix::kNone;

  char back = view->back();

  if (back == 'f' || back == 'F') {
    *view = view->substr(0, view->size() - 1);
    return FloatSuffix::kFloat;
  }

  if (back == 'l' || back == 'L') {
    *view = view->substr(0, view->size() - 1);
    return FloatSuffix::kLong;
  }

  return FloatSuffix::kNone;
}

ErrOrValue ValueForFloatToken(ExprLanguage lang, const ExprToken& token) {
  FX_DCHECK(token.type() == ExprTokenType::kFloat);

  std::string_view value = token.value();
  FloatSuffix suffix = StripFloatSuffix(&value);
  if (lang != ExprLanguage::kC && suffix == FloatSuffix::kLong)
    suffix = FloatSuffix::kNone;  // Only C has a "long double" type.

  double_conversion::StringToDoubleConverter converter(0, 0.0, nan(""), nullptr, nullptr);

  fxl::RefPtr<BaseType> type;
  std::vector<uint8_t> data;

  int consumed = 0;
  switch (suffix) {
    case FloatSuffix::kNone: {
      double d = converter.StringToDouble(value.data(), static_cast<int>(value.size()), &consumed);
      data.resize(sizeof(double));
      memcpy(&data[0], &d, sizeof(double));
      type = GetBuiltinDoubleType(lang);
      break;
    }
    case FloatSuffix::kFloat: {
      float f = converter.StringToFloat(value.data(), static_cast<int>(value.size()), &consumed);
      data.resize(sizeof(float));
      memcpy(&data[0], &f, sizeof(float));
      type = GetBuiltinFloatType(lang);
      break;
    }
    case FloatSuffix::kLong: {
      // The parser doesn't support long doubles, but we can at least upcast if the local system
      // supports it.
      double d = converter.StringToDouble(value.data(), static_cast<int>(value.size()), &consumed);
      long double ld = d;
      data.resize(sizeof(long double));
      memcpy(&data[0], &ld, sizeof(long double));
      type = GetBuiltinLongDoubleType(lang);
      break;
    }
  }

  if (consumed != static_cast<int>(value.size()))
    return Err("Trailing characters on floating-point constant.");

  return ExprValue(std::move(type), std::move(data));
}

}  // namespace zxdb
