// 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_rust_tuple.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/expr/resolve_collection.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 {

void PrettyRustTuple::Format(FormatNode* node, const FormatOptions& options,
                             const fxl::RefPtr<EvalContext>& context, fit::deferred_callback cb) {
  auto collection = node->value().type()->AsCollection();

  if (collection->GetSpecialType() == Collection::kRustTupleStruct) {
    node->set_description_kind(FormatNode::kRustTupleStruct);
  } else {
    node->set_description_kind(FormatNode::kRustTuple);
  }

  // Rust tuple (and tuple struct) symbols have the tuple members encoded as "__0", "__1", etc.
  for (const auto& lazy_member : collection->data_members()) {
    const DataMember* member = lazy_member.Get()->AsDataMember();
    if (!member)
      continue;

    // Convert the names to indices "__0" -> 0.
    auto name = member->GetAssignedName();
    if (name.size() > 2 && name[0] == '_' && name[1] == '_')
      name.erase(name.begin(), name.begin() + 2);

    // In the error case, still append a child so that the child can have the error associated
    // with it.
    node->children().push_back(std::make_unique<FormatNode>(
        name, ResolveNonstaticMember(context, node->value(), FoundMember(collection, member))));
  }
}

PrettyRustTuple::EvalFunction PrettyRustTuple::GetMember(const std::string& getter_name) const {
  if (getter_name.empty()) {
    return EvalFunction();
  }

  for (const auto& ch : getter_name) {
    if (ch < '0' || ch > '9') {
      return EvalFunction();
    }
  }

  return [getter_name](const fxl::RefPtr<EvalContext>& context, const ExprValue& object_value,
                       EvalCallback cb) {
    // Rust tuple members are named __0, __1, etc.
    EvalExpressionOn(context, object_value, "__" + getter_name, std::move(cb));
  };
}

void PrettyRustZirconStatus::Format(FormatNode* node, const FormatOptions& options,
                                    const fxl::RefPtr<EvalContext>& context,
                                    fit::deferred_callback cb) {
  auto collection = node->value().type()->AsCollection();
  if (!collection || collection->GetSpecialType() != Collection::kRustTupleStruct) {
    return;
  }

  node->set_description_kind(FormatNode::kRustTupleStruct);

  const auto& members = collection->data_members();
  if (members.size() != 1) {
    return;
  }

  if (const DataMember* member = members[0].Get()->AsDataMember()) {
    auto child = std::make_unique<FormatNode>(
        "0", ResolveNonstaticMember(context, node->value(), FoundMember(collection, member)));

    // The status formatter can return immediately, meaning this node gets printed before this
    // function is done, so we have to share the return callback, not just pass it along.
    auto shared_cb = std::make_shared<fit::deferred_callback>(std::move(cb));

    PrettyZxStatusT status_formatter;
    status_formatter.Format(child.get(), options, context,
                            fit::defer_callback([shared_cb]() mutable {}));

    child->set_state(FormatNode::kDescribed);
    child->set_source(FormatNode::kDescription);

    node->children().push_back(std::move(child));
  }
}

}  // namespace zxdb
