// 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) {
  FXL_DCHECK(byte < 0x10);

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

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

}  // namespace

bool DecodeByteString(const char hex[2], uint8_t* out_byte) {
  FXL_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]) {
  FXL_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) {
    FXL_LOG(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) {
  FXL_DCHECK(buffer);

  size_t index = 0, count = 0;
  for (const auto& str : strings) {
    FXL_DCHECK(index + str.length() <= buffer_size);
    memcpy(buffer + index, str.data(), str.length());
    index += str.length();
    if (++count == strings.size())
      break;
    FXL_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
