// 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 "src/developer/debug/debug_agent/debugged_thread.h"

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/debugged_process.h"
#include "src/developer/debug/debug_agent/mock_debug_agent_harness.h"
#include "src/developer/debug/debug_agent/mock_exception_handle.h"
#include "src/developer/debug/debug_agent/mock_process.h"
#include "src/developer/debug/debug_agent/mock_process_handle.h"
#include "src/developer/debug/debug_agent/mock_thread.h"
#include "src/developer/debug/debug_agent/mock_thread_handle.h"
#include "src/developer/debug/debug_agent/remote_api.h"

namespace debug_agent {

using namespace debug_ipc;

namespace {

TEST(DebuggedThread, Resume) {
  MockDebugAgentHarness harness;

  constexpr zx_koid_t kProcessKoid = 0x8723456;
  MockProcess process(harness.debug_agent(), kProcessKoid);

  constexpr zx_koid_t kThreadKoid = 0x8723457;
  MockThread* thread = process.AddThread(kThreadKoid);
  EXPECT_FALSE(thread->in_exception());

  ExceptionHandle::Resolution resolution = ExceptionHandle::Resolution::kTryNext;
  debug_ipc::ExceptionStrategy exception_strategy = debug_ipc::ExceptionStrategy::kNone;
  auto exception = std::make_unique<MockExceptionHandle>(
      [&resolution](ExceptionHandle::Resolution new_res) { resolution = new_res; },
      [&exception_strategy](debug_ipc::ExceptionStrategy new_strategy) {
        exception_strategy = new_strategy;
      });
  thread->set_exception_handle(std::move(exception));
  EXPECT_TRUE(thread->in_exception());
  thread->ClientResume(
      debug_ipc::ResumeRequest{.how = debug_ipc::ResumeRequest::How::kResolveAndContinue});
  EXPECT_FALSE(thread->in_exception());
  EXPECT_EQ(resolution, ExceptionHandle::Resolution::kHandled);
  EXPECT_EQ(exception_strategy, debug_ipc::ExceptionStrategy::kNone);

  resolution = ExceptionHandle::Resolution::kTryNext;
  exception_strategy = debug_ipc::ExceptionStrategy::kNone;
  exception = std::make_unique<MockExceptionHandle>(
      [&resolution](ExceptionHandle::Resolution new_res) { resolution = new_res; },
      [&exception_strategy](debug_ipc::ExceptionStrategy new_strategy) {
        exception_strategy = new_strategy;
      });
  thread->set_exception_handle(std::move(exception));
  EXPECT_TRUE(thread->in_exception());
  thread->ClientResume(
      debug_ipc::ResumeRequest{.how = debug_ipc::ResumeRequest::How::kForwardAndContinue});
  EXPECT_FALSE(thread->in_exception());
  EXPECT_EQ(resolution, ExceptionHandle::Resolution::kTryNext);
  EXPECT_EQ(exception_strategy, debug_ipc::ExceptionStrategy::kSecondChance);
}

TEST(DebuggedThread, OnException) {
  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  constexpr zx_koid_t kProcessKoid = 0x8723456;
  MockProcess process(harness.debug_agent(), kProcessKoid);

  constexpr zx_koid_t kThreadKoid = 0x8723457;
  MockThread* thread = process.AddThread(kThreadKoid);
  EXPECT_FALSE(thread->in_exception());

  // Policy: general exceptions initially handled as first-chance.
  // Exception: general, first-chance.
  // Expected: no applied strategy.
  {
    debug_ipc::ExceptionStrategy applied_strategy = debug_ipc::ExceptionStrategy::kNone;
    auto exception = std::make_unique<MockExceptionHandle>(
        [](ExceptionHandle::Resolution) {},
        [&applied_strategy](debug_ipc::ExceptionStrategy new_strategy) {
          applied_strategy = new_strategy;
        });
    exception->set_type(debug_ipc::ExceptionType::kGeneral);
    exception->SetStrategy(debug_ipc::ExceptionStrategy::kFirstChance);
    applied_strategy = debug_ipc::ExceptionStrategy::kNone;  // Clear previously set.

    thread->OnException(std::move(exception));

    EXPECT_EQ(debug_ipc::ExceptionStrategy::kNone, applied_strategy);
  }

  // Policy: general exceptions initially handled as first-chance.
  // Exception: general, second-chance.
  // Expected: no applied strategy (as this isn't our initial handling).
  {
    debug_ipc::ExceptionStrategy applied_strategy = debug_ipc::ExceptionStrategy::kNone;
    auto exception = std::make_unique<MockExceptionHandle>(
        [](ExceptionHandle::Resolution) {},
        [&applied_strategy](debug_ipc::ExceptionStrategy new_strategy) {
          applied_strategy = new_strategy;
        });
    exception->set_type(debug_ipc::ExceptionType::kGeneral);
    exception->SetStrategy(debug_ipc::ExceptionStrategy::kSecondChance);
    applied_strategy = debug_ipc::ExceptionStrategy::kNone;  // Clear previously set.

    thread->OnException(std::move(exception));

    EXPECT_EQ(debug_ipc::ExceptionStrategy::kNone, applied_strategy);
  }

  // Update policy so that general exceptions are handled initially as
  // second-chance.
  const debug_ipc::UpdateGlobalSettingsRequest request = {
      .exception_strategies =
          {
              {
                  .type = debug_ipc::ExceptionType::kGeneral,
                  .value = debug_ipc::ExceptionStrategy::kSecondChance,
              },
          },
  };
  debug_ipc::UpdateGlobalSettingsReply reply;
  remote_api->OnUpdateGlobalSettings(request, &reply);
  EXPECT_EQ(ZX_OK, reply.status);

  // Policy: general exceptions initially handled as second-chance.
  // Exception: general, first-chance.
  // Expected: applied strategy of second-chance.
  {
    debug_ipc::ExceptionStrategy applied_strategy = debug_ipc::ExceptionStrategy::kNone;
    auto exception = std::make_unique<MockExceptionHandle>(
        [](ExceptionHandle::Resolution) {},
        [&applied_strategy](debug_ipc::ExceptionStrategy new_strategy) {
          applied_strategy = new_strategy;
        });
    exception->set_type(debug_ipc::ExceptionType::kGeneral);
    exception->SetStrategy(debug_ipc::ExceptionStrategy::kFirstChance);
    applied_strategy = debug_ipc::ExceptionStrategy::kNone;  // Clear previously set.

    thread->OnException(std::move(exception));

    EXPECT_EQ(debug_ipc::ExceptionStrategy::kSecondChance, applied_strategy);
    // Since we didn't handle the exception, we expect it to have been closed.
    EXPECT_EQ(nullptr, thread->exception_handle());
  }

  // Policy: general exceptions initially handled as second-chance.
  // Exception: general, second-chance.
  // Expected: no applied strategy.
  {
    debug_ipc::ExceptionStrategy applied_strategy = debug_ipc::ExceptionStrategy::kNone;
    auto exception = std::make_unique<MockExceptionHandle>(
        [](ExceptionHandle::Resolution) {},
        [&applied_strategy](debug_ipc::ExceptionStrategy new_strategy) {
          applied_strategy = new_strategy;
        });
    exception->set_type(debug_ipc::ExceptionType::kGeneral);
    exception->SetStrategy(debug_ipc::ExceptionStrategy::kSecondChance);
    applied_strategy = debug_ipc::ExceptionStrategy::kNone;  // Clear previously set.

    thread->OnException(std::move(exception));

    EXPECT_EQ(debug_ipc::ExceptionStrategy::kNone, applied_strategy);
  }
}

}  // namespace

}  // namespace debug_agent
