// Copyright 2020 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 "profile_manager.h"

#include <fuchsia/scheduler/cpp/fidl.h>
#include <lib/zx/handle.h>
#include <lib/zx/status.h>
#include <zircon/syscalls.h>

#include <future>
#include <thread>

#include <gtest/gtest.h>

#include "src/lib/testing/predicates/status.h"
#include "testing_util.h"

namespace hwstress {
namespace {

TEST(ProfileManager, ApplyProfiles) {
  std::unique_ptr<ProfileManager> manager = ProfileManager::CreateFromEnvironment();
  ASSERT_TRUE(manager != nullptr);

  // Create a child thread that just blocks on a future.
  std::promise<bool> should_wake;
  auto worker =
      std::make_unique<std::thread>([wake = should_wake.get_future()]() mutable { wake.get(); });

  // Set thread priority.
  EXPECT_OK(manager->SetThreadPriority(worker.get(), /*priority=*/1));

  // Set thread affinity.
  EXPECT_OK(manager->SetThreadAffinity(worker.get(), /*mask=*/1));

  // Ensure our affinity has been set correctly. (The kernel doesn't provide priority
  // information.)
  zx_info_thread info;
  ASSERT_OK(HandleFromThread(worker.get())
                ->get_info(ZX_INFO_THREAD, &info, sizeof(info), nullptr, nullptr));
  EXPECT_EQ(info.cpu_affinity_mask.mask[0], 0x1ul);

  // Clean up our child thread.
  should_wake.set_value(true);
  worker->join();
}

struct FakeProfileProvider : public fuchsia::scheduler::ProfileProvider {
  FakeProfileProvider() = default;

  void GetProfile(uint32_t priority, std::string name, GetProfileCallback callback) override {
    ASSERT_TRUE(!get_profile_called);
    get_profile_called = true;
    requested_priority = priority;
    callback(ZX_OK, zx::profile(0));
  }

  void GetCpuAffinityProfile(fuchsia::scheduler::CpuSet cpu_mask,
                             GetCpuAffinityProfileCallback callback) override {
    get_affinity_profile_called = true;
    requested_mask = cpu_mask;
    callback(ZX_OK, zx::profile(0));
  }

  void GetDeadlineProfile(uint64_t capacity, uint64_t deadline, uint64_t period, std::string name,
                          GetDeadlineProfileCallback callback) override {
    ZX_PANIC("unexpected call");
  }

  void SetProfileByRole(zx::thread thread, std::string role,
                        SetProfileByRoleCallback callback) override {
    ZX_PANIC("unexpected call");
  }

  bool get_affinity_profile_called = false;
  bool get_profile_called = false;
  uint32_t requested_priority = -1;
  fuchsia::scheduler::CpuSet requested_mask{};
};

TEST(ProfileManager, ProfileProviderCalled) {
  testing::LoopbackConnectionFactory factory;

  // Create a connection to a FakeProfileProvider.
  FakeProfileProvider provider;
  ProfileManager manager(factory.CreateSyncPtrTo<fuchsia::scheduler::ProfileProvider>(&provider));

  // Create a child thread that just blocks on a future.
  std::promise<bool> should_wake;
  auto worker =
      std::make_unique<std::thread>([wake = should_wake.get_future()]() mutable { wake.get(); });

  // Set thread priority. The fake gives us an invalid handle, so ignore the error.
  (void)manager.SetThreadPriority(worker.get(), /*priority=*/13);
  EXPECT_TRUE(provider.get_profile_called);
  EXPECT_EQ(provider.requested_priority, 13u);

  // Set thread affinity. The fake gives us an invalid handle, so ignore the error.
  (void)manager.SetThreadAffinity(worker.get(), /*mask=*/0xaa55);
  EXPECT_TRUE(provider.get_affinity_profile_called);
  EXPECT_EQ(provider.requested_mask.mask[0], 0xaa55ul);

  // Clean up our child thread.
  should_wake.set_value(true);
  worker->join();
}

}  // namespace
}  // namespace hwstress
