// Copyright 2018 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 "garnet/bin/zxdb/console/format_memory.h"

#include <inttypes.h>

#include <limits>

#include "garnet/bin/zxdb/client/memory_dump.h"
#include "garnet/public/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

const char kUnknownByte[] = "??";
const char kNonAscii =
    ' ';  // When printing ASCII and the character is not in range.

bool IsPrintableAscii(uint8_t c) { return c >= ' ' && c < 0x7f; }

}  // namespace

// Optimized for simplicity over speed. But this does not use the table output
// to avoid having giant table computations for large memory dumps.
std::string FormatMemory(const MemoryDump& dump, uint64_t begin, uint32_t size,
                         const MemoryFormatOptions& opts) {
  std::string out;

  // Compute the last address we'll print. Watch for overflow.
  uint64_t max_addr = std::numeric_limits<uint64_t>::max();
  if (max_addr - size > begin)
    max_addr = begin + size - 1;

  // Max address character width.
  int addr_width = 0;
  if (opts.show_addrs) {
    addr_width =
        static_cast<int>(fxl::StringPrintf("%" PRIx64, max_addr).size());
  }

  uint64_t cur = begin;  // Current address being printed.
  std::string line;      // These string buffers are outside the loop to prevent
                         // reallocation.
  std::string address;
  std::string values;
  std::string ascii;
  bool done = false;
  while (!done) {  // Line loop
    // Compute address at beginning of line.
    if (opts.show_addrs) {
      address = fxl::StringPrintf("0x%0*" PRIx64, addr_width, cur);
      address.append(":  ");
    }

    values.clear();
    ascii.clear();
    for (int i = 0; i < opts.values_per_line; i++) {  // Value loop.
      // Separator between values.
      if (i > 0) {
        if (!done && opts.separator_every > 0 &&
            (i % opts.separator_every) == 0) {
          values.push_back('-');
        } else {
          values.push_back(' ');
        }
      }

      if (!done) {
        uint8_t byte;
        if (dump.GetByte(cur, &byte)) {
          values += fxl::StringPrintf("%02x", static_cast<int>(byte));
          if (IsPrintableAscii(byte)) {
            ascii.push_back(static_cast<char>(byte));
          } else {
            ascii.push_back(kNonAscii);
          }
        } else {
          values.append(kUnknownByte);
          ascii.push_back(kNonAscii);
        }

        // Carefully only increment address if it won't overflow.
        if (cur == max_addr) {
          done = true;
        } else {
          cur++;
        }
      } else {
        // Line is done, but we still want padding for values.
        values.append("  ");
        ascii.push_back(' ');
      }
    }

    // Append the constructed elements.
    out.append(address);  // Will be empty if not showing.
    out.append(values);
    if (opts.show_ascii) {
      out.append("  |");
      out.append(ascii);
    }
    out.push_back('\n');

    address.clear();
    values.clear();
  }

  return out;
}

}  // namespace zxdb
