// 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) && src) {
    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 && ('x' == *src || 'X' == *src)) {
          ++src;
          base = 16;
        }
      }
    }

    // For performance in common cases, use the templated conversion.
    switch (base) {
      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
