// 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 <gtest/gtest.h>

#include "src/developer/debug/zxdb/client/mock_frame.h"
#include "src/developer/debug/zxdb/client/mock_remote_api.h"
#include "src/developer/debug/zxdb/client/remote_api_test.h"
#include "src/developer/debug/zxdb/console/mock_console.h"

namespace zxdb {

namespace {

using debug::MessageLoop;

class MemoryMockRemoteAPI : public MockRemoteAPI {
 public:
  // Return an empty AddressSpace reply.
  void AddressSpace(const debug_ipc::AddressSpaceRequest& request,
                    fit::callback<void(const Err&, debug_ipc::AddressSpaceReply)> cb) override {
    MessageLoop::Current()->PostTask(
        FROM_HERE, [cb = std::move(cb)]() mutable { cb(Err(), debug_ipc::AddressSpaceReply()); });
  }
};

class VerbsMemoryTest : public RemoteAPITest {
 public:
  std::unique_ptr<RemoteAPI> GetRemoteAPIImpl() {
    auto remote_api = std::make_unique<MemoryMockRemoteAPI>();
    memory_mock_remote_api_ = remote_api.get();
    return remote_api;
  }

  MemoryMockRemoteAPI* memory_mock_remote_api() const { return memory_mock_remote_api_; }

 private:
  MemoryMockRemoteAPI* memory_mock_remote_api_ = nullptr;  // Owned by System.
};

}  // namespace

// This tests that the stack command is hooked up. The register and memory decoding are tested by
// the analyze memory tests.
//
// TODO(brettw) convert to a ConsoleTest to remove some boilerplate.
TEST_F(VerbsMemoryTest, Stack) {
  MockConsole console(&session());

  // Error case with nothing running.
  console.ProcessInputLine("stack");
  auto event = console.GetOutputEvent();
  ASSERT_EQ(MockConsole::OutputEvent::Type::kOutput, event.type);
  ASSERT_EQ("\"stack\" requires a thread but there is no current thread.", event.output.AsString());

  // Inject a fake running process.
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  // Eat the output from process attaching (this is asynchronously appended).
  loop().RunUntilNoTasks();
  console.FlushOutputEvents();

  // Error case with no stopped thread.
  console.ProcessInputLine("stack");
  event = console.GetOutputEvent();
  EXPECT_EQ(MockConsole::OutputEvent::Type::kOutput, event.type);
  EXPECT_EQ(
      "\"stack\" requires a suspended thread but thread 1 is Running.\n"
      "To view and sync thread state with the remote system, type \"thread\".\n"
      "Or type \"pause\" to pause a running thread.",
      event.output.AsString());

  // Thread needs to be stopped. Add two frames with some different registers.
  constexpr uint64_t kIP0 = 0x987654321;
  constexpr uint64_t kSP0 = 0x10000000;
  constexpr uint64_t kIP1 = kIP0 - 0x10;
  constexpr uint64_t kSP1 = kSP0 + 0x10;
  std::vector<std::unique_ptr<Frame>> frames;
  frames.push_back(std::make_unique<MockFrame>(
      &session(), thread, Location(Location::State::kSymbolized, kIP0), kSP0, 0,
      std::vector<debug::RegisterValue>{debug::RegisterValue(debug::RegisterID::kX64_rsp, kSP0)}));
  frames.push_back(std::make_unique<MockFrame>(
      &session(), thread, Location(Location::State::kSymbolized, kIP1), kSP1, 0,
      std::vector<debug::RegisterValue>{
          debug::RegisterValue(debug::RegisterID::kX64_rsp, kSP1),
          debug::RegisterValue(debug::RegisterID::kX64_rax, kSP0 + 0x20)}));
  InjectExceptionWithStack(kProcessKoid, kThreadKoid, debug_ipc::ExceptionType::kSingleStep,
                           std::move(frames), true);

  // Eat output from the exception.
  loop().RunUntilNoTasks();
  console.FlushOutputEvents();

  // Supply some memory.
  std::vector<uint8_t> mem_data;
  mem_data.resize(1024);
  mem_data[0] = 0xff;
  mem_data[1] = 0xee;
  memory_mock_remote_api()->AddMemory(kSP0, mem_data);

  console.ProcessInputLine("stack");

  loop().RunUntilNoTasks();

  event = console.GetOutputEvent();
  ASSERT_EQ(MockConsole::OutputEvent::Type::kOutput, event.type);
  ASSERT_EQ(
      "   Address               Data \n"
      "0x10000000 0x000000000000eeff ◁ rsp\n"
      "0x10000008 0x0000000000000000 \n"
      "0x10000010 0x0000000000000000 ◁ frame 1 rsp\n"
      "0x10000018 0x0000000000000000 \n"
      "0x10000020 0x0000000000000000 ◁ frame 1 rax\n"
      "0x10000028 0x0000000000000000 \n"
      "0x10000030 0x0000000000000000 \n"
      "0x10000038 0x0000000000000000 \n"
      "0x10000040 0x0000000000000000 \n"
      "0x10000048 0x0000000000000000 \n"
      "0x10000050 0x0000000000000000 \n"
      "0x10000058 0x0000000000000000 \n"
      "0x10000060 0x0000000000000000 \n"
      "0x10000068 0x0000000000000000 \n"
      "0x10000070 0x0000000000000000 \n"
      "0x10000078 0x0000000000000000 \n"
      "0x10000080 0x0000000000000000 \n"
      "0x10000088 0x0000000000000000 \n"
      "0x10000090 0x0000000000000000 \n"
      "0x10000098 0x0000000000000000 \n"
      "↓ For more lines: stack -n 20 0x100000a0",
      event.output.AsString());
}

}  // namespace zxdb
