// Copyright 2016 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 "util.h"

#include <cctype>
#include <cinttypes>
#include <cstring>

#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace debugger_utils {

namespace {

bool HexCharToByte(char hex_char, uint8_t* out_byte) {
  if (hex_char >= 'a' && hex_char <= 'f') {
    *out_byte = hex_char - 'a' + 10;
    return true;
  }

  if (hex_char >= '0' && hex_char <= '9') {
    *out_byte = hex_char - '0';
    return true;
  }

  if (hex_char >= 'A' && hex_char <= 'F') {
    *out_byte = hex_char - 'A' + 10;
    return true;
  }

  return false;
}

char HalfByteToHexChar(uint8_t byte) {
  FX_DCHECK(byte < 0x10);

  if (byte < 10)
    return '0' + byte;

  return 'a' + (byte % 10);
}

}  // namespace

bool DecodeByteString(const char hex[2], uint8_t* out_byte) {
  FX_DCHECK(out_byte);

  uint8_t msb, lsb;
  if (!HexCharToByte(hex[0], &msb) || !HexCharToByte(hex[1], &lsb))
    return false;

  *out_byte = lsb | (msb << 4);
  return true;
}

void EncodeByteString(const uint8_t byte, char out_hex[2]) {
  FX_DCHECK(out_hex);

  out_hex[0] = HalfByteToHexChar(byte >> 4);
  out_hex[1] = HalfByteToHexChar(byte & 0x0f);
}

std::string EncodeByteArrayString(const uint8_t* bytes, size_t num_bytes) {
  const size_t kResultSize = num_bytes * 2;
  if (!kResultSize)
    return "";

  std::string result;
  result.resize(kResultSize);
  for (size_t i = 0; i < kResultSize; i += 2) {
    EncodeByteString(*bytes, const_cast<char*>(result.data() + i));
    ++bytes;
  }

  return result;
}

std::string EncodeString(const fxl::StringView& string) {
  auto bytes = reinterpret_cast<const uint8_t*>(string.data());
  return EncodeByteArrayString(bytes, string.size());
}

std::vector<uint8_t> DecodeByteArrayString(const fxl::StringView& string) {
  std::vector<uint8_t> result;
  if (string.size() % 2) {
    FX_LOGS(ERROR) << "Byte array string must have an even number of characters";
    return result;
  }

  if (string.empty())
    return result;

  const size_t kResultSize = string.size() / 2;
  result.resize(kResultSize);
  for (size_t i = 0; i < kResultSize; ++i) {
    if (!DecodeByteString(string.data() + (i * 2), result.data() + i))
      return std::vector<uint8_t>{};
  }

  return result;
}

std::string DecodeString(const fxl::StringView& string) {
  std::vector<uint8_t> charvec = DecodeByteArrayString(string);
  return std::string(charvec.begin(), charvec.end());
}

std::string EscapeNonPrintableString(const fxl::StringView& data) {
  std::string result;
  for (char c : data) {
    if (std::isprint(c)) {
      result.push_back(c);
      continue;
    }

    char str[4];
    str[0] = '\\';
    str[1] = 'x';
    EncodeByteString(static_cast<uint8_t>(c), str + 2);
    result.append(str, sizeof(str));
  }

  return result;
}

std::string ErrnoString(int err) { return fxl::StringPrintf("%s(%d)", strerror(err), err); }

size_t JoinStrings(const std::deque<std::string>& strings, const char delimiter, char* buffer,
                   size_t buffer_size) {
  FX_DCHECK(buffer);

  size_t index = 0, count = 0;
  for (const auto& str : strings) {
    FX_DCHECK(index + str.length() <= buffer_size);
    memcpy(buffer + index, str.data(), str.length());
    index += str.length();
    if (++count == strings.size())
      break;
    FX_DCHECK(index < buffer_size);
    buffer[index++] = delimiter;
  }

  return index;
}

char* xstrdup(const char* s) {
  char* result = strdup(s);
  if (!result) {
    fprintf(stderr, "strdup OOM\n");
    exit(1);
  }
  return result;
}

const char* basename(const char* path) {
  const char* base = strrchr(path, '/');
  if (base == nullptr)
    return path;
  return base + 1;
}

#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))

void hexdump_ex(FILE* out, const void* ptr, size_t len, uint64_t disp_addr) {
  uintptr_t address = (uintptr_t)ptr;
  size_t count;

  for (count = 0; count < len; count += 16) {
    union {
      uint32_t buf[4];
      uint8_t cbuf[16];
    } u;
    size_t s = ROUNDUP(MIN(len - count, 16), 4);
    size_t i;

    fprintf(out, ((disp_addr + len) > 0xFFFFFFFF) ? "0x%016" PRIx64 ": " : "0x%08" PRIx64 ": ",
            disp_addr + count);

    for (i = 0; i < s / 4; i++) {
      u.buf[i] = ((const uint32_t*)address)[i];
      fprintf(out, "%08x ", u.buf[i]);
    }
    for (; i < 4; i++) {
      fprintf(out, "         ");
    }
    fprintf(out, "|");

    for (i = 0; i < 16; i++) {
      char c = u.cbuf[i];
      if (i < s && isprint(c)) {
        fprintf(out, "%c", c);
      } else {
        fprintf(out, ".");
      }
    }
    fprintf(out, "|\n");
    address += 16;
  }
}

}  // namespace debugger_utils
