// Copyright 2024 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/register_utils.h"

#include "src/developer/debug/shared/register_info.h"
#include "src/developer/debug/zxdb/expr/builtin_types.h"
#include "src/developer/debug/zxdb/expr/find_name.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"

namespace zxdb {

debug::RegisterID GetRegisterID(debug::Arch arch, const ParsedIdentifier& ident) {
  // Check for explicit register identifier annotation.
  if (ident.components().size() == 1 &&
      ident.components()[0].special() == SpecialIdentifier::kRegister) {
    return debug::StringToRegisterID(arch, ident.components()[0].name());
  }

  // Try to convert the identifier string to a register name.
  auto str = GetSingleComponentIdentifierName(ident);
  if (!str)
    return debug::RegisterID::kUnknown;
  return debug::StringToRegisterID(arch, *str);
}

Err GetUnavailableRegisterErr(debug::RegisterID id) {
  return Err("Register %s unavailable in this context.", debug::RegisterIDToString(id));
}

ErrOrValue RegisterDataToValue(ExprLanguage lang, debug::RegisterID id,
                               VectorRegisterFormat vector_fmt, cpp20::span<const uint8_t> data) {
  const debug::RegisterInfo* info = debug::InfoForRegister(id);
  if (!info)
    return Err("Unknown register");

  ExprValueSource source(id);

  switch (info->format) {
    case debug::RegisterFormat::kGeneral:
    case debug::RegisterFormat::kSpecial: {
      return ExprValue(GetBuiltinUnsignedType(lang, data.size()),
                       std::vector<uint8_t>(data.begin(), data.end()), source);
    }

    case debug::RegisterFormat::kFloat: {
      return ExprValue(GetBuiltinFloatType(lang, data.size()),
                       std::vector<uint8_t>(data.begin(), data.end()), source);
    }

    case debug::RegisterFormat::kVector: {
      return VectorRegisterToValue(id, vector_fmt, std::vector<uint8_t>(data.begin(), data.end()));
    }

    case debug::RegisterFormat::kVoidAddress: {
      // A void* is a pointer to no type.
      return ExprValue(fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, LazySymbol()),
                       std::vector<uint8_t>(data.begin(), data.end()), source);
    }

    case debug::RegisterFormat::kWordAddress: {
      auto word_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType,
                                                             GetBuiltinUnsignedType(lang, 8));
      return ExprValue(word_ptr_type, std::vector<uint8_t>(data.begin(), data.end()), source);
    }
  }

  return Err("Unknown register type");
}

}  // namespace zxdb
