// 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;

int
memcmp(std::string_view const &lhs, std::string_view const &rhs)
{
  int zret = 0;
  size_t n = rhs.size();

  // Seems a bit ugly but size comparisons must be done anyway to get the memcmp args.
  if (lhs.size() < rhs.size()) {
    zret = 1;
    n    = lhs.size();
  } else if (lhs.size() > rhs.size()) {
    zret = -1;
  } else if (lhs.data() == rhs.data()) { // same memory, obviously equal.
    return 0;
  }

  int r = ::memcmp(lhs.data(), rhs.data(), n);
  return r ? r : zret;
}

int
strcasecmp(const std::string_view &lhs, const std::string_view &rhs)
{
  int zret = 0;
  size_t n = rhs.size();

  // Seems a bit ugly but size comparisons must be done anyway to get the @c strncasecmp args.
  if (lhs.size() < rhs.size()) {
    zret = 1;
    n    = lhs.size();
  } else if (lhs.size() > rhs.size()) {
    zret = -1;
  } else if (lhs.data() == rhs.data()) { // the same memory, obviously equal.
    return 0;
  }

  int r = ::strncasecmp(lhs.data(), rhs.data(), n);

  return r ? r : zret;
}

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

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
