// Copyright 2019 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 "src/developer/debug/zxdb/expr/pretty_std_string.h"

#include "src/developer/debug/zxdb/expr/format.h"
#include "src/developer/debug/zxdb/expr/format_node.h"
#include "src/developer/debug/zxdb/expr/format_options.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/symbol_data_provider.h"

namespace zxdb {

namespace {

// A hardcoded pretty-printer for our std::string implementation.
//
// Long-term, we'll want a better pretty-printing system that's more extensible and versionable
// with our C++ library. This is a first step to designing such a system.
//
// In libc++ std::string is an "extern template" which means that the char specialization of
// basic_string is in the shared library. Without symbols for libc++, there is no definition for
// std::string.
//
// As of this writing our libc++ doesn't have symbols, and it's also nice to allow people to
// print strings in their own program without all of the lib++ symbols (other containers don't
// require this so it can be surprising).
//
// As a result, this pretty-printer is designed to work with no symbol information, and getting
// a value with no size (the expression evaluator won't know what size to make in many cases).
// This complicates it considerably, but std::string is likely the only class that will need such
// handling.
//
// THE DEFINITION
// --------------
//
// Our libc++'s std::string implementation has two modes, a "short" mode where the string is stored
// inline in the string object, and a "long" mode where it stores a pointer to a heap-allocated
// buffer. These modes are differentiated with a bit on the last byte of the storage.
//
//   class basic_string {
//     // For little-endian:
//     static const size_type __short_mask = 0x80;
//     static const size_type __long_mask  = ~(size_type(~0) >> 1);  // High bit set.
//
//     bool is_long() const {return __r_.__s.__size_ & __short_mask; }
//
//     struct __rep {
//       // Long is used when "__s.__size_ & __short_mask" is true.
//       union {
//         struct __long {
//           value_type* __data_;
//           size_t __size_;
//           size_t __cap_;  // & with __long_mask to get.
//         } __l;
//
//         struct __short {
//           char value_type[23]
//           // padding of sizeof(char) - 1
//           struct {
//             unsigned char __size_;
//           };
//         } __s;
//
//         __raw __r;  // Can ignore, used only for rapidly copying the representation.
//       };
//     };
//
//     // actually "__compressed_pair<__rep, allocator> __r_" but effectively:
//     compressed_pair __r_;
//   };

constexpr uint32_t kStdStringSize = 24;

// Offset from beginning of the object to "__short.__size_" (last byte).
constexpr size_t kShortSizeOffset = 23;

// Bit that indicates the "short" representation.
constexpr uint64_t kShortMask = 0x80;

// Offsets within the data for the "long" representation.
constexpr uint64_t kLongPtrOffset = 0;
constexpr uint64_t kLongSizeOffset = 8;
constexpr uint64_t kLongCapacityOffset = 16;

fxl::RefPtr<BaseType> GetStdStringCharType() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
}
fxl::RefPtr<BaseType> GetSizeTType() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, 8, "size_t");
}

// Returns true if this std::string uses the inline representation. It's assumed the data has
// al;ready been validated as being the correct length.
bool IsInlineString(const std::vector<uint8_t>& mem) {
  FX_DCHECK(mem.size() == kStdStringSize);
  return !(mem[kShortSizeOffset] & kShortMask);
}

// Fills in the data pointer for the given std::string.
Err GetStringPtr(const ExprValue& value, uint64_t* ptr) {
  if (value.data().size() != kStdStringSize)
    return Err("Invalid std::string data.");

  if (IsInlineString(value.data())) {
    // The address is just the beginning of the string.
    if (value.source().type() != ExprValueSource::Type::kMemory || value.source().address() == 0)
      return Err("Can't get string pointer to a temporary.");
    *ptr = value.source().address();
  } else {
    memcpy(ptr, &value.data()[kLongPtrOffset], sizeof(uint64_t));
  }
  return Err();
}

Err GetStringSize(const std::vector<uint8_t>& mem, uint64_t* size) {
  if (mem.size() != kStdStringSize)
    return Err("Invalid std::string data.");

  if (IsInlineString(mem))
    *size = mem[kShortSizeOffset];
  else
    memcpy(size, &mem[kLongSizeOffset], sizeof(uint64_t));
  return Err();
}

Err GetStringCapacity(const std::vector<uint8_t>& mem, uint64_t* capacity) {
  if (mem.size() != kStdStringSize)
    return Err("Invalid std::string data.");

  if (IsInlineString(mem)) {
    *capacity = kShortSizeOffset - 1;  // Inline size is stuff before the short size minus null.
  } else {
    memcpy(capacity, &mem[kLongCapacityOffset], sizeof(uint64_t));

    // Mask off the high bit which is the "large" flag.
    *capacity &= 0x7fffffffffffffff;
  }
  return Err();
}

void FormatStdStringMemory(const std::vector<uint8_t>& mem, FormatNode* node,
                           const FormatOptions& options, const fxl::RefPtr<EvalContext>& context,
                           fit::deferred_callback cb) {
  node->set_type("std::string");
  if (mem.size() != kStdStringSize)
    return node->SetDescribedError(Err("Invalid."));

  auto char_type = GetStdStringCharType();

  uint64_t string_size = 0;
  if (Err err = GetStringSize(mem, &string_size); err.has_error())
    return node->SetDescribedError(err);

  if (IsInlineString(mem)) {
    FormatCharArrayNode(node, char_type, &mem[0], string_size, true, false);
  } else {
    // Long representation (with pointer).
    uint64_t data_ptr;
    memcpy(&data_ptr, &mem[kLongPtrOffset], sizeof(uint64_t));
    FormatCharPointerNode(node, data_ptr, char_type.get(), string_size, options, context,
                          std::move(cb));
  }
}

// Normally when we have a std::string we won't have the data because the definition is
// missing. But the "source" will usually be set and we can go fetch the right amount of data.
// This function calls the callback with a populated ExprValue if it can be made to have the correct
// size.
void EnsureStdStringMemory(const fxl::RefPtr<EvalContext>& context, const ExprValue& value,
                           EvalCallback cb) {
  if (value.data().size() != 0) {
    if (value.data().size() == kStdStringSize)
      return cb(value);
    return cb(Err("Invalid std::string type size."));
  }

  // Don't have the data, see if we can fetch it.
  if (value.source().type() != ExprValueSource::Type::kMemory || value.source().address() == 0)
    return cb(Err("Can't handle a temporary std::string."));

  context->GetDataProvider()->GetMemoryAsync(
      value.source().address(), kStdStringSize,
      [value, cb = std::move(cb)](const Err& err, std::vector<uint8_t> data) mutable {
        if (err.has_error())
          cb(err);
        else if (data.size() != kStdStringSize)
          cb(Err("Invalid memory."));
        else
          cb(ExprValue(value.type_ref(), std::move(data), value.source()));
      });
}

// Getters all need to do the same thing: ensure memory, error check, and then run on the result.
// This returns a callback that does that stuff, with the given "getter" implementation taking
// a complete string of a known correct size.
PrettyStdString::EvalFunction MakeGetter(fit::function<void(ExprValue, EvalCallback)> getter) {
  return [getter = std::move(getter)](const fxl::RefPtr<EvalContext>& context,
                                      const ExprValue& object_value, EvalCallback cb) mutable {
    EnsureStdStringMemory(
        context, object_value,
        [context, cb = std::move(cb), getter = std::move(getter)](ErrOrValue value) mutable {
          if (value.has_error())
            return cb(value);
          getter(value.value(), std::move(cb));
        });
  };
}

}  // namespace

void PrettyStdString::Format(FormatNode* node, const FormatOptions& options,
                             const fxl::RefPtr<EvalContext>& context, fit::deferred_callback cb) {
  EnsureStdStringMemory(context, node->value(),
                        [weak_node = node->GetWeakPtr(), options, context,
                         cb = std::move(cb)](ErrOrValue value) mutable {
                          if (!weak_node)
                            return;
                          if (value.has_error()) {
                            weak_node->set_err(value.err());
                            weak_node->set_state(FormatNode::kDescribed);
                          } else {
                            FormatStdStringMemory(value.value().data(), weak_node.get(), options,
                                                  context, std::move(cb));
                          }
                        });
}

PrettyStdString::EvalFunction PrettyStdString::GetGetter(const std::string& getter_name) const {
  if (getter_name == "data" || getter_name == "c_str") {
    return MakeGetter([](ExprValue value, EvalCallback cb) {
      uint64_t ptr = 0;
      if (Err err = GetStringPtr(value, &ptr); err.has_error())
        return cb(err);

      auto char_ptr =
          fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, GetStdStringCharType());
      cb(ExprValue(ptr, char_ptr));
    });
  }
  if (getter_name == "size" || getter_name == "length") {
    return MakeGetter([](ExprValue value, EvalCallback cb) {
      uint64_t string_size = 0;
      if (Err err = GetStringSize(value.data(), &string_size); err.has_error())
        cb(err);
      cb(ExprValue(string_size, GetSizeTType()));
    });
  }
  if (getter_name == "capacity") {
    return MakeGetter([](ExprValue value, EvalCallback cb) {
      uint64_t cap = 0;
      if (Err err = GetStringCapacity(value.data(), &cap); err.has_error())
        return cb(err);
      cb(ExprValue(cap, GetSizeTType()));
    });
  }
  if (getter_name == "empty") {
    return MakeGetter([](ExprValue value, EvalCallback cb) {
      uint64_t string_size = 0;
      if (Err err = GetStringSize(value.data(), &string_size); err.has_error())
        return cb(err);
      cb(ExprValue(string_size == 0));
    });
  }

  return EvalFunction();
}

PrettyStdString::EvalArrayFunction PrettyStdString::GetArrayAccess() const {
  return [](const fxl::RefPtr<EvalContext>& context, const ExprValue& object_value, int64_t index,
            EvalCallback cb) {
    EnsureStdStringMemory(
        context, object_value, [context, cb = std::move(cb), index](ErrOrValue value) mutable {
          if (value.has_error())
            return cb(value.err());
          if (IsInlineString(value.value().data())) {
            // Use the inline data. Need to range check since we're indexing into our local
            // address space.
            if (index >= static_cast<int64_t>(kShortSizeOffset) || index < 0)
              return cb(Err("String index out of range."));

            // Inline array starts from the beginning of the string.
            return cb(ExprValue(GetStdStringCharType(), {value.value().data()[index]},
                                value.value().source().GetOffsetInto(index)));
          } else {
            uint64_t ptr = 0;
            if (Err err = GetStringPtr(value.value(), &ptr); err.has_error())
              return cb(err);

            context->GetDataProvider()->GetMemoryAsync(
                ptr, 1,
                [context, ptr, cb = std::move(cb)](const Err& err,
                                                   std::vector<uint8_t> data) mutable {
                  if (err.has_error())
                    return cb(err);
                  if (data.size() == 0)
                    return cb(Err("Invalid address 0x%" PRIx64, ptr));

                  cb(ExprValue(GetStdStringCharType(), {data[0]}, ExprValueSource(ptr)));
                });
          }
        });
  };
}

}  // namespace zxdb
