// 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/client/system.h"

#include <gtest/gtest.h>

#include "src/developer/debug/shared/zx_status.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/job.h"
#include "src/developer/debug/zxdb/client/mock_remote_api.h"
#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/process_observer.h"
#include "src/developer/debug/zxdb/client/remote_api_test.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/developer/debug/zxdb/client/system_observer.h"
#include "src/developer/debug/zxdb/client/target_observer.h"
#include "src/developer/debug/zxdb/client/thread.h"

namespace zxdb {

namespace {

struct ProcessInfo {
  uint64_t koid;
  std::string name;
};

class APISink : public MockRemoteAPI {
 public:
  void Attach(const debug_ipc::AttachRequest& request,
              fit::callback<void(const Err&, debug_ipc::AttachReply)> cb) override {
    attach_requests_.push_back(request);

    FX_DCHECK(info_count_ < next_infos_.size());
    auto info = next_infos_[info_count_++];

    debug_ipc::AttachReply reply;
    reply.status = debug_ipc::kZxOk;
    reply.koid = info.koid;
    reply.name = info.name;
    cb(Err(), std::move(reply));
  }

  const std::vector<debug_ipc::AttachRequest>& attach_requests() const { return attach_requests_; }

  // Sets the list of replys the sink will return.
  void SetNextInfos(std::vector<ProcessInfo> infos) {
    next_infos_ = std::move(infos);
    info_count_ = 0;
  }

  void UpdateGlobalSettings(
      const debug_ipc::UpdateGlobalSettingsRequest& request,
      fit::callback<void(const Err&, debug_ipc::UpdateGlobalSettingsReply)> cb) override {
    global_setting_requests_.push_back(request);
    debug_ipc::UpdateGlobalSettingsReply reply = {.status = debug_ipc::kZxOk};
    cb(Err(), std::move(reply));
  }

  const std::vector<debug_ipc::UpdateGlobalSettingsRequest>& global_setting_requests() const {
    return global_setting_requests_;
  }

 private:
  size_t info_count_ = 0;
  std::vector<ProcessInfo> next_infos_;
  std::vector<debug_ipc::AttachRequest> attach_requests_;
  std::vector<debug_ipc::UpdateGlobalSettingsRequest> global_setting_requests_;
};

class SystemTest : public RemoteAPITest {
 public:
  SystemTest() = default;
  ~SystemTest() override = default;

  APISink* sink() { return sink_; }

 private:
  std::unique_ptr<RemoteAPI> GetRemoteAPIImpl() override {
    auto sink = std::make_unique<APISink>();
    // The session will own the sink.
    sink_ = sink.get();
    return sink;
  }

  APISink* sink_;
};

// We need a RAII-esque wrapper because observers are supposed to outlive the system.
class MockSystemObserver : public TargetObserver, public ProcessObserver {
 public:
  explicit MockSystemObserver(Session* session) : session_(session) {
    session->target_observers().AddObserver(this);
    session->process_observers().AddObserver(this);
  }
  ~MockSystemObserver() {
    session_->process_observers().RemoveObserver(this);
    session_->target_observers().RemoveObserver(this);
  }

  // TargetObserver.
  void DidCreateTarget(Target*) override { target_create_count_++; }

  // ProcessObserver.
  void DidCreateProcess(Process*, bool) override { process_create_count_++; }

  int target_create_count() const { return target_create_count_; }
  int process_create_count() const { return process_create_count_; }

 private:
  Session* session_ = nullptr;

  int target_create_count_ = 0;
  int process_create_count_ = 0;
};

}  // namespace

// Tests that thread state is updated when doing a system-wide continue.
TEST_F(SystemTest, GlobalContinue) {
  // Make a process and thread for notifying about.
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThread1Koid = 5678;
  Thread* thread1 = InjectThread(kProcessKoid, kThread1Koid);
  constexpr uint64_t kThread2Koid = 9012;
  Thread* thread2 = InjectThread(kProcessKoid, kThread2Koid);
  sink()->GetAndResetResumeCount();  // Clear from thread init.

  constexpr uint64_t kAddress = 0x12345678;
  constexpr uint64_t kStack = 0x7890;

  // Notify of thread stop on thread 1.
  debug_ipc::NotifyException break_notification;
  break_notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  break_notification.thread.process_koid = kProcessKoid;
  break_notification.thread.thread_koid = kThread1Koid;
  break_notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  break_notification.thread.frames.emplace_back(kAddress, kStack, kStack);
  InjectException(break_notification);
  EXPECT_EQ(0, sink()->GetAndResetResumeCount());

  // Same on thread 2.
  break_notification.thread.thread_koid = kThread2Koid;
  InjectException(break_notification);

  // Continue globally. This should in turn update the thread.
  session().system().Continue(false);

  // Both threads should have been resumed in the backend.
  EXPECT_EQ(2, sink()->GetAndResetResumeCount());

  // The threads should have no stack.
  EXPECT_FALSE(thread1->GetStack().has_all_frames());
  ASSERT_EQ(0u, thread1->GetStack().size());
  EXPECT_FALSE(thread2->GetStack().has_all_frames());
  ASSERT_EQ(0u, thread2->GetStack().size());
}

TEST_F(SystemTest, FilterMatchesAndRematching) {
  System& system = session().system();
  MockSystemObserver system_observer(&session());

  constexpr uint64_t kJobKoid = 0x1234;
  Job job(&session(), false);
  job.AttachForTesting(kJobKoid, "job-name");
  ASSERT_TRUE(sink()->attach_requests().empty());

  // There should be only one empty target.
  auto targets = system.GetTargets();
  ASSERT_EQ(targets.size(), 1u);
  EXPECT_FALSE(targets[0]->GetProcess());

  // We match on a new process.
  constexpr uint64_t kProcessKoid = 0x5678;
  std::string kProcessName = "some-process";
  ProcessInfo info = {kProcessKoid, kProcessName};
  sink()->SetNextInfos({info});

  session().system().OnFilterMatches(&job, {kProcessKoid});

  // There should be an attach request.
  auto& requests = sink()->attach_requests();
  ASSERT_EQ(requests.size(), 1u);
  EXPECT_EQ(requests[0].type, debug_ipc::TaskType::kProcess);
  EXPECT_EQ(requests[0].koid, kProcessKoid);

  // The system should've reused the empty target.
  ASSERT_EQ(system_observer.target_create_count(), 0);
  targets = system.GetTargets();
  ASSERT_EQ(targets.size(), 1u);

  // Should've created the process.
  ASSERT_EQ(system_observer.process_create_count(), 1);
  Process* process = targets[0]->GetProcess();
  ASSERT_TRUE(process);
  EXPECT_EQ(process->GetKoid(), kProcessKoid);
  EXPECT_EQ(process->GetName(), kProcessName);

  // Rematching should not create a new target.
  sink()->SetNextInfos({info});

  session().system().OnFilterMatches(&job, {kProcessKoid});

  // The system should've reused the empty target.
  ASSERT_EQ(system_observer.target_create_count(), 0);
  targets = system.GetTargets();
  ASSERT_EQ(targets.size(), 1u);

  // Should've created the process.
  ASSERT_EQ(system_observer.process_create_count(), 1);
  process = targets[0]->GetProcess();
  ASSERT_TRUE(process);
  EXPECT_EQ(process->GetKoid(), kProcessKoid);
  EXPECT_EQ(process->GetName(), kProcessName);
}

TEST_F(SystemTest, ExistenProcessShouldCreateTarget) {
  System& system = session().system();
  MockSystemObserver system_observer(&session());

  constexpr uint64_t kJobKoid = 0x1234;
  Job job(&session(), false);
  job.AttachForTesting(kJobKoid, "job-name");
  ASSERT_TRUE(sink()->attach_requests().empty());

  // Before injecting the process there should not be an event, after it there should be one.
  ASSERT_EQ(system_observer.process_create_count(), 0);
  constexpr uint64_t kProcessKoid1 = 0x1;
  InjectProcess(kProcessKoid1);
  ASSERT_EQ(system_observer.process_create_count(), 1);

  // There should be a target with a process.
  auto targets = system.GetTargets();
  ASSERT_EQ(targets.size(), 1u);
  Process* process = targets[0]->GetProcess();
  ASSERT_TRUE(process);
  ASSERT_EQ(process->GetKoid(), kProcessKoid1);

  // We match on a new process.
  constexpr uint64_t kProcessKoid2 = 0x2;
  std::string kProcessName = "some-process";
  ProcessInfo info = {kProcessKoid2, kProcessName};
  sink()->SetNextInfos({info});

  session().system().OnFilterMatches(&job, {kProcessKoid2});

  // There should be an attach request.
  auto& requests = sink()->attach_requests();
  ASSERT_EQ(requests.size(), 1u);
  EXPECT_EQ(requests[0].type, debug_ipc::TaskType::kProcess);
  EXPECT_EQ(requests[0].koid, kProcessKoid2);

  // The system should've created a new target.
  ASSERT_EQ(system_observer.target_create_count(), 1);
  targets = system.GetTargets();
  ASSERT_EQ(targets.size(), 2u);

  // Should've created the process.
  ASSERT_EQ(system_observer.process_create_count(), 2);
  process = targets[1]->GetProcess();
  ASSERT_TRUE(process);
  EXPECT_EQ(process->GetKoid(), kProcessKoid2);
  EXPECT_EQ(process->GetName(), kProcessName);
}

TEST_F(SystemTest, UpdateSecondChanceExceptions) {
  System& system = session().system();
  {
    system.settings().SetList(ClientSettings::System::kSecondChanceExceptions, {"pf"});
    ASSERT_EQ(1u, sink()->global_setting_requests().size());
    auto& request = sink()->global_setting_requests()[0];
    std::set<debug_ipc::ExceptionType> second_chance_excps;
    for (const auto& update : request.exception_strategies) {
      if (update.value == debug_ipc::ExceptionStrategy::kSecondChance) {
        second_chance_excps.insert(update.type);
      }
    }
    EXPECT_EQ(std::set({debug_ipc::ExceptionType::kPageFault}), second_chance_excps);
  }

  {
    system.settings().SetList(ClientSettings::System::kSecondChanceExceptions, {"gen", "ua"});
    ASSERT_EQ(2u, sink()->global_setting_requests().size());
    auto& request = sink()->global_setting_requests()[1];
    std::set<debug_ipc::ExceptionType> second_chance_excps;
    for (const auto& update : request.exception_strategies) {
      if (update.value == debug_ipc::ExceptionStrategy::kSecondChance) {
        second_chance_excps.insert(update.type);
      }
    }
    EXPECT_EQ(
        std::set({debug_ipc::ExceptionType::kGeneral, debug_ipc::ExceptionType::kUnalignedAccess}),
        second_chance_excps);
  }
}

}  // namespace zxdb
