// 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/client/register.h"
#include "garnet/bin/zxdb/client/session.h"
#include "garnet/bin/zxdb/client/thread.h"
#include "gtest/gtest.h"

namespace zxdb {

using debug_ipc::RegisterCategory;
using debug_ipc::RegisterID;

namespace {

std::vector<uint8_t> CreateData(size_t length) {
  std::vector<uint8_t> data;
  data.reserve(length);
  // So that we get the number backwards (0x0102...).
  uint8_t base = length;
  for (size_t i = 0; i < length; i++) {
    data.emplace_back(base - i);
  }
  return data;
}

debug_ipc::Register CreateRegister(RegisterID id, size_t length) {
  debug_ipc::Register reg;
  reg.id = id;
  reg.data = CreateData(length);
  return reg;
}

}  // namespace

TEST(Register, CorrectlyCreatesBoundaries) {
  debug_ipc::Register ipc_reg = CreateRegister(RegisterID::kARMv8_x0, 1);
  Register reg(ipc_reg);
  ASSERT_EQ(reg.size(), 1u);
  ASSERT_EQ((size_t)(reg.end() - reg.begin()), ipc_reg.data.size());
  EXPECT_EQ(reg.GetValue(), 0x01u);
  auto it = reg.begin();
  EXPECT_EQ(*it++, ipc_reg.data[0]);
  EXPECT_EQ(it, reg.end());

  ipc_reg = CreateRegister(RegisterID::kARMv8_x1, 2);
  reg = Register(ipc_reg);
  ASSERT_EQ(reg.size(), 2u);
  ASSERT_EQ((size_t)(reg.end() - reg.begin()), ipc_reg.data.size());
  EXPECT_EQ(reg.GetValue(), 0x0102u);
  it = reg.begin();
  EXPECT_EQ(*it++, ipc_reg.data[0]);
  EXPECT_EQ(*it++, ipc_reg.data[1]);
  EXPECT_EQ(it, reg.end());

  ipc_reg = CreateRegister(RegisterID::kARMv8_lr, 4);
  reg = Register(ipc_reg);
  ASSERT_EQ(reg.size(), 4u);
  ASSERT_EQ((size_t)(reg.end() - reg.begin()), ipc_reg.data.size());
  EXPECT_EQ(reg.GetValue(), 0x01020304u);
  it = reg.begin();
  EXPECT_EQ(*it++, ipc_reg.data[0]);
  EXPECT_EQ(*it++, ipc_reg.data[1]);
  EXPECT_EQ(*it++, ipc_reg.data[2]);
  EXPECT_EQ(*it++, ipc_reg.data[3]);
  EXPECT_EQ(it, reg.end());

  ipc_reg = CreateRegister(RegisterID::kARMv8_cpsr, 8);
  reg = Register(ipc_reg);
  ASSERT_EQ(reg.size(), 8u);
  ASSERT_EQ((size_t)(reg.end() - reg.begin()), ipc_reg.data.size());
  EXPECT_EQ(reg.GetValue(), 0x0102030405060708u);
  it = reg.begin();
  EXPECT_EQ(*it++, ipc_reg.data[0]);
  EXPECT_EQ(*it++, ipc_reg.data[1]);
  EXPECT_EQ(*it++, ipc_reg.data[2]);
  EXPECT_EQ(*it++, ipc_reg.data[3]);
  EXPECT_EQ(*it++, ipc_reg.data[4]);
  EXPECT_EQ(*it++, ipc_reg.data[5]);
  EXPECT_EQ(*it++, ipc_reg.data[6]);
  EXPECT_EQ(*it++, ipc_reg.data[7]);
  EXPECT_EQ(it, reg.end());

  ipc_reg = CreateRegister(RegisterID::kARMv8_x11, 16);
  reg = Register(ipc_reg);
  ASSERT_EQ(reg.size(), 16u);
  ASSERT_EQ((size_t)(reg.end() - reg.begin()), ipc_reg.data.size());
  it = reg.begin();
  EXPECT_EQ(*it++, ipc_reg.data[0]);
  EXPECT_EQ(*it++, ipc_reg.data[1]);
  EXPECT_EQ(*it++, ipc_reg.data[2]);
  EXPECT_EQ(*it++, ipc_reg.data[3]);
  EXPECT_EQ(*it++, ipc_reg.data[4]);
  EXPECT_EQ(*it++, ipc_reg.data[5]);
  EXPECT_EQ(*it++, ipc_reg.data[6]);
  EXPECT_EQ(*it++, ipc_reg.data[7]);
  EXPECT_EQ(*it++, ipc_reg.data[8]);
  EXPECT_EQ(*it++, ipc_reg.data[9]);
  EXPECT_EQ(*it++, ipc_reg.data[10]);
  EXPECT_EQ(*it++, ipc_reg.data[11]);
  EXPECT_EQ(*it++, ipc_reg.data[12]);
  EXPECT_EQ(*it++, ipc_reg.data[13]);
  EXPECT_EQ(*it++, ipc_reg.data[14]);
  EXPECT_EQ(*it++, ipc_reg.data[15]);
  EXPECT_EQ(it, reg.end());
}

TEST(RegisterSet, RegisterMap) {
  std::vector<RegisterCategory> categories;
  RegisterCategory cat1;
  cat1.type = RegisterCategory::Type::kGeneral;
  cat1.registers.push_back(CreateRegister(RegisterID::kARMv8_lr, 2));
  cat1.registers.push_back(CreateRegister(RegisterID::kARMv8_pc, 4));
  categories.push_back(cat1);

  // Sanity check
  ASSERT_EQ(*(uint8_t*)&(cat1.registers[0].data[0]), 0x02u);
  ASSERT_EQ(*(uint16_t*)&(cat1.registers[1].data[0]), 0x0304u);

  RegisterCategory cat2;
  cat2.type = RegisterCategory::Type::kVector;
  cat2.registers.push_back(CreateRegister(RegisterID::kARMv8_x0, 2));
  cat2.registers.push_back(CreateRegister(RegisterID::kARMv8_x1, 4));
  categories.push_back(cat2);

  RegisterSet set(debug_ipc::Arch::kArm64, categories);

  const Register* reg = set[RegisterID::kARMv8_lr];
  ASSERT_TRUE(reg);
  EXPECT_EQ(reg->id(), RegisterID::kARMv8_lr);
  EXPECT_EQ(reg->GetValue(), 0x0102u);

  reg = set[RegisterID::kARMv8_x1];
  ASSERT_TRUE(reg);
  EXPECT_EQ(reg->id(), RegisterID::kARMv8_x1);
  EXPECT_EQ(reg->GetValue(), 0x01020304u);
}

TEST(RegisterSet, DWARFMappings) {
  std::vector<RegisterCategory> categories;
  RegisterCategory cat1;
  cat1.type = RegisterCategory::Type::kGeneral;
  cat1.registers.push_back(CreateRegister(RegisterID::kARMv8_sp, 2));
  cat1.registers.push_back(CreateRegister(RegisterID::kARMv8_cpsr, 4));
  categories.push_back(cat1);

  // Sanity check
  ASSERT_EQ(*(uint8_t*)&(cat1.registers[0].data[0]), 0x02u);
  ASSERT_EQ(*(uint16_t*)&(cat1.registers[1].data[0]), 0x0304u);

  RegisterCategory cat2;
  cat2.type = RegisterCategory::Type::kVector;
  cat2.registers.push_back(CreateRegister(RegisterID::kARMv8_x0, 2));
  cat2.registers.push_back(CreateRegister(RegisterID::kARMv8_x1, 4));
  categories.push_back(cat2);

  RegisterSet set(debug_ipc::Arch::kArm64, categories);

  const Register* reg = set.GetRegisterFromDWARF(1);
  ASSERT_TRUE(reg);
  EXPECT_EQ(reg->id(), RegisterID::kARMv8_x1);
  EXPECT_EQ(reg->GetValue(), 0x01020304u);
  uint64_t val;
  ASSERT_TRUE(set.GetRegisterValueFromDWARF(1, &val));
  EXPECT_EQ(val, 0x01020304u);

  reg = set.GetRegisterFromDWARF(32);
  ASSERT_TRUE(reg);
  EXPECT_EQ(reg->id(), RegisterID::kARMv8_sp);
  EXPECT_EQ(reg->GetValue(), 0x0102u);
  ASSERT_TRUE(set.GetRegisterValueFromDWARF(32, &val));
  EXPECT_EQ(val, 0x0102u);

  reg = set.GetRegisterFromDWARF(10000);
  EXPECT_FALSE(reg);

  // Wrong architecture
  set.set_arch(debug_ipc::Arch::kX64);
  for (size_t i = 0; i < 40; i++)
    ASSERT_FALSE(set.GetRegisterFromDWARF(i));
}

}  // namespace zxdb
