// SPDX-License-Identifier: Apache-2.0
// Copyright Apache Software Foundation 2019
/** @file

    Class for handling "views" of a buffer. Views presume the memory for the
    buffer is managed elsewhere and allow efficient access to segments of the
    buffer without copies. Views are read only as the view doesn't own the
    memory. Along with generic buffer methods are specialized methods to support
    better string parsing, particularly token based parsing.
*/

#include "swoc/TextView.h"
#include <cctype>
#include <sstream>

using namespace swoc::literals;

namespace swoc { inline namespace SWOC_VERSION_NS {

/// @cond INTERNAL_DETAIL
const int8_t svtoi_convert[256] = {
  /* [can't do this nicely because clang format won't allow exdented comments]
   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  */
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20
  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  -1, -1, -1, -1, -1, -1, // 30
  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40
  25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 50
  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 60
  25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 70
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // A0
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // B0
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // C0
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // D0
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // E0
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // F0
};
/// @endcond

intmax_t
svtoi(TextView src, TextView *out, int base) {
  intmax_t zret = 0;

  if (src.ltrim_if(&isspace)) {
    TextView parsed;
    const char *start = src.data();
    bool neg          = false;
    if ('-' == *src) {
      ++src;
      neg = true;
    } else if ('+' == *src) {
      ++src;
    }
    zret = intmax_t(svtou(src, &parsed, base));
    if (!parsed.empty()) {
      if (out) {
        out->assign(start, parsed.data_end());
      }
      if (neg) {
        zret = -zret;
      }
    }
  }
  return zret;
}

uintmax_t
svtou(TextView src, TextView *out, int base) {
  uintmax_t zret = 0;

  if (out) {
    out->clear();
  }
  if (!(0 <= base && base <= 36)) {
    return 0;
  }
  if (src.ltrim_if(&isspace).size()) {
    auto origin = src.data();
    int8_t v;
    // If base is 0, it wasn't specified - check for standard base prefixes
    if (0 == base) {
      base = 10;
      if ('0' == *src) {
        ++src;
        base = 8;
        if (src) {
          switch (*src) {
          case 'x':
          case 'X':
            ++src;
            base = 16;
            break;
          case 'b':
          case 'B':
            ++src;
            base = 2;
            break;
          }
        }
      }
    }

    // For performance in common cases, use the templated conversion.
    switch (base) {
    case 2:
      zret = svto_radix<2>(src);
      break;
    case 8:
      zret = svto_radix<8>(src);
      break;
    case 10:
      zret = svto_radix<10>(src);
      break;
    case 16:
      zret = svto_radix<16>(src);
      break;
    default:
      while (src.size() && (0 <= (v = svtoi_convert[static_cast<unsigned char>(*src)])) && v < base) {
        auto n = zret * base + v;
        if (n < zret) {
          zret = std::numeric_limits<uintmax_t>::max();
          break; // overflow, stop parsing.
        }
        zret = n;
        ++src;
      }
      break;
    }

    if (out) {
      out->assign(origin, src.data());
    }
  }
  return zret;
}

double
svtod(swoc::TextView text, swoc::TextView *parsed) {
  // @return 10^e
  auto pow10 = [](int e) -> double {
    double zret  = 1.0;
    double scale = 10.0;
    if (e < 0) { // flip the scale and make @a e positive.
      e     = -e;
      scale = 0.1;
    }

    // Walk the bits in the exponent @a e and multiply the scale for set bits.
    while (e) {
      if (e & 1) {
        zret *= scale;
      }
      scale *= scale;
      e >>= 1;
    }
    return zret;
  };

  if (text.empty()) {
    return 0;
  }

  auto org_text = text; // save this to update @a parsed.
  // Check just once and dump to a local copy if needed.
  TextView local_parsed;
  if (!parsed) {
    parsed = &local_parsed;
  }

  // Handle leading sign.
  int sign = 1;
  if (*text == '-') {
    ++text;
    sign = -1;
  } else if (*text == '+') {
    ++text;
  }
  // Parse the leading whole part as an integer.
  intmax_t whole = svto_radix<10>(text);
  parsed->assign(org_text.data(), text.data());

  if (text.empty()) {
    return whole;
  }

  double frac = 0.0;
  if (*text == '.') { // fractional part.
    ++text;
    double scale = 0.1;
    while (text && isdigit(*text)) {
      frac += scale * (*text++ - '0');
      scale /= 10.0;
    }
  }

  double exp = 1.0;
  if (text.starts_with_nocase("e")) {
    int exp_sign = 1;
    ++text;
    if (text) {
      if (*text == '+') {
        ++text;
      } else if (*text == '-') {
        ++text;
        exp_sign = -1;
      }
    }
    auto exp_part = svto_radix<10>(text);
    exp           = pow10(exp_part * exp_sign);
  }

  parsed->assign(org_text.data(), text.data());
  return sign * (whole + frac) * exp;
}

// Do the template instantiations.
template std::ostream &TextView::stream_write(std::ostream &, const TextView &) const;

}} // namespace swoc::SWOC_VERSION_NS

namespace std {
ostream &
operator<<(ostream &os, const swoc::TextView &b) {
  if (os.good()) {
    b.stream_write<ostream>(os, b);
    os.width(0);
  }
  return os;
}
} // namespace std
