// 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()->As<Collection>();

  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()->As<DataMember>();
    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()->As<Collection>();
  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()->As<DataMember>()) {
    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
