// 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 "aml-cpu.h"

#include <fidl/fuchsia.hardware.thermal/cpp/wire.h>
#include <fuchsia/hardware/thermal/cpp/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async_patterns/testing/cpp/dispatcher_bound.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/device-protocol/pdev-fidl.h>

#include <algorithm>
#include <memory>
#include <vector>

#include <ddktl/device.h>
#include <ddktl/fidl.h>
#include <fake-mmio-reg/fake-mmio-reg.h>
#include <fbl/array.h>
#include <sdk/lib/inspect/testing/cpp/zxtest/inspect.h>
#include <soc/aml-common/aml-cpu-metadata.h>
#include <zxtest/zxtest.h>

#include "src/devices/bus/testing/fake-pdev/fake-pdev.h"
#include "src/devices/testing/mock-ddk/mock-device.h"

namespace amlogic_cpu {

// Fake MMIO  that exposes CPU version.
class FakeMmio {
 public:
  FakeMmio() : mmio_(sizeof(uint32_t), kRegCount) {
    mmio_[kCpuVersionOffset].SetReadCallback([]() { return kCpuVersion; });
  }

  fdf::MmioBuffer mmio() { return mmio_.GetMmioBuffer(); }

 private:
  static constexpr size_t kCpuVersionOffset = 0x220;
  static constexpr size_t kRegCount = kCpuVersionOffset / sizeof(uint32_t) + 1;

  // Note: FakeMmioReg's read callback returns a uint64_t, which is then cast to uint32_t when
  // AmlCpu calls FakeMmioRegRegion::Read32.
  constexpr static uint64_t kCpuVersion = 43;

  ddk_fake::FakeMmioRegRegion mmio_;
};

using CpuCtrlSyncClient = fidl::WireSyncClient<fuchsia_cpuctrl::Device>;
using ThermalSyncClient = fidl::WireSyncClient<fuchsia_thermal::Device>;

constexpr size_t kBigClusterIdx =
    static_cast<size_t>(fuchsia_thermal::wire::PowerDomain::kBigClusterPowerDomain);
constexpr size_t kLittleClusterIdx =
    static_cast<size_t>(fuchsia_thermal::wire::PowerDomain::kLittleClusterPowerDomain);

constexpr uint32_t kBigClusterCoreCount = 4;
constexpr uint32_t kLittleClusterCoreCount = 2;

constexpr legacy_cluster_size_t kClusterSizeMetadata[] = {
    {
        .pd_id = kBigClusterIdx,
        .core_count = kBigClusterCoreCount,
    },
    {
        .pd_id = kLittleClusterIdx,
        .core_count = kLittleClusterCoreCount,
    },
};

constexpr size_t PowerDomainToIndex(fuchsia_thermal::wire::PowerDomain pd) {
  switch (pd) {
    case fuchsia_thermal::wire::PowerDomain::kLittleClusterPowerDomain:
      return kLittleClusterIdx;
    case fuchsia_thermal::wire::PowerDomain::kBigClusterPowerDomain:
      return kBigClusterIdx;
  }
  __UNREACHABLE;
}

const fuchsia_thermal::wire::OperatingPoint kFakeOperatingPoints = []() {
  fuchsia_thermal::wire::OperatingPoint result;

  result.count = 3;
  result.latency = 0;
  result.opp[0].volt_uv = 1;
  result.opp[0].freq_hz = 100;
  result.opp[1].volt_uv = 2;
  result.opp[1].freq_hz = 200;
  result.opp[2].volt_uv = 3;
  result.opp[2].freq_hz = 300;

  return result;
}();

const fuchsia_thermal::wire::ThermalDeviceInfo kDefaultDeviceInfo = []() {
  fuchsia_thermal::wire::ThermalDeviceInfo result;

  result.active_cooling = false;
  result.passive_cooling = false;
  result.gpu_throttling = false;
  result.num_trip_points = 0;
  result.big_little = false;
  result.critical_temp_celsius = 0;

  result.opps[kLittleClusterIdx].count = 0;
  result.opps[kBigClusterIdx] = kFakeOperatingPoints;

  return result;
}();

class FakeAmlThermal : public fidl::WireServer<fuchsia_thermal::Device> {
 public:
  FakeAmlThermal() : active_operating_point_(0), device_info_(kDefaultDeviceInfo) {}
  ~FakeAmlThermal() {}

  // Manage the Fake FIDL Message Loop
  zx_status_t Init(fidl::ServerEnd<fuchsia_thermal::Device> remote);

  // Accessor
  uint16_t ActiveOperatingPoint() const { return active_operating_point_; }

  void DdkRelease() {}

  void set_device_info(const fuchsia_thermal::wire::ThermalDeviceInfo& device_info) {
    device_info_ = device_info;
  }

 private:
  // Implement Thermal FIDL Protocol.
  void GetInfo(GetInfoCompleter::Sync& completer) override;
  void GetDeviceInfo(GetDeviceInfoCompleter::Sync& completer) override;
  void GetDvfsInfo(GetDvfsInfoRequestView request, GetDvfsInfoCompleter::Sync& completer) override;
  void GetTemperatureCelsius(GetTemperatureCelsiusCompleter::Sync& completer) override;
  void GetSensorName(GetSensorNameCompleter::Sync& completer) override {}
  void GetStateChangeEvent(GetStateChangeEventCompleter::Sync& completer) override;
  void GetStateChangePort(GetStateChangePortCompleter::Sync& completer) override;
  void SetTripCelsius(SetTripCelsiusRequestView request,
                      SetTripCelsiusCompleter::Sync& completer) override;
  void GetDvfsOperatingPoint(GetDvfsOperatingPointRequestView request,
                             GetDvfsOperatingPointCompleter::Sync& completer) override;
  void SetDvfsOperatingPoint(SetDvfsOperatingPointRequestView request,
                             SetDvfsOperatingPointCompleter::Sync& completer) override;
  void GetFanLevel(GetFanLevelCompleter::Sync& completer) override;
  void SetFanLevel(SetFanLevelRequestView request, SetFanLevelCompleter::Sync& completer) override;

  uint16_t active_operating_point_;
  async::Loop loop_{&kAsyncLoopConfigNeverAttachToThread};
  fuchsia_thermal::wire::ThermalDeviceInfo device_info_;
};

zx_status_t FakeAmlThermal::Init(fidl::ServerEnd<fuchsia_thermal::Device> request) {
  loop_.StartThread("fake-aml-thermal");
  fidl::BindServer(loop_.dispatcher(), std::move(request), this, nullptr);
  return ZX_OK;
}

void FakeAmlThermal::GetInfo(GetInfoCompleter::Sync& completer) {
  fuchsia_thermal::wire::ThermalInfo result;

  result.state = 0;
  result.passive_temp_celsius = 0;
  result.critical_temp_celsius = 0;
  result.max_trip_count = 0;

  completer.Reply(ZX_OK,
                  fidl::ObjectView<fuchsia_thermal::wire::ThermalInfo>::FromExternal(&result));
}

void FakeAmlThermal::GetDeviceInfo(GetDeviceInfoCompleter::Sync& completer) {
  fuchsia_thermal::wire::ThermalDeviceInfo result = device_info_;
  completer.Reply(
      ZX_OK, fidl::ObjectView<fuchsia_thermal::wire::ThermalDeviceInfo>::FromExternal(&result));
}

void FakeAmlThermal::GetDvfsInfo(GetDvfsInfoRequestView request,
                                 GetDvfsInfoCompleter::Sync& completer) {
  fuchsia_thermal::wire::ThermalDeviceInfo device_info = device_info_;
  fuchsia_thermal::wire::OperatingPoint result =
      device_info.opps[PowerDomainToIndex(request->power_domain)];
  completer.Reply(ZX_OK,
                  fidl::ObjectView<fuchsia_thermal::wire::OperatingPoint>::FromExternal(&result));
}

void FakeAmlThermal::GetTemperatureCelsius(GetTemperatureCelsiusCompleter::Sync& completer) {
  completer.Reply(ZX_OK, 0.0);
}

void FakeAmlThermal::GetStateChangeEvent(GetStateChangeEventCompleter::Sync& completer) {
  zx::event invalid;
  completer.Reply(ZX_ERR_NOT_SUPPORTED, std::move(invalid));
}

void FakeAmlThermal::GetStateChangePort(GetStateChangePortCompleter::Sync& completer) {
  zx::port invalid;
  completer.Reply(ZX_ERR_NOT_SUPPORTED, std::move(invalid));
}

void FakeAmlThermal::SetTripCelsius(SetTripCelsiusRequestView request,
                                    SetTripCelsiusCompleter::Sync& completer) {
  completer.Reply(ZX_ERR_NOT_SUPPORTED);
}

void FakeAmlThermal::GetDvfsOperatingPoint(GetDvfsOperatingPointRequestView request,
                                           GetDvfsOperatingPointCompleter::Sync& completer) {
  if (request->power_domain == fuchsia_thermal::wire::PowerDomain::kLittleClusterPowerDomain) {
    completer.Reply(ZX_ERR_NOT_SUPPORTED, 0);
    return;
  }

  completer.Reply(ZX_OK, active_operating_point_);
}

void FakeAmlThermal::SetDvfsOperatingPoint(SetDvfsOperatingPointRequestView request,
                                           SetDvfsOperatingPointCompleter::Sync& completer) {
  if (request->power_domain == fuchsia_thermal::wire::PowerDomain::kLittleClusterPowerDomain) {
    completer.Reply(ZX_ERR_NOT_SUPPORTED);
    return;
  }

  active_operating_point_ = request->op_idx;
  completer.Reply(ZX_OK);
}

void FakeAmlThermal::GetFanLevel(GetFanLevelCompleter::Sync& completer) {
  completer.Reply(ZX_ERR_NOT_SUPPORTED, 0);
}

void FakeAmlThermal::SetFanLevel(SetFanLevelRequestView request,
                                 SetFanLevelCompleter::Sync& completer) {
  completer.Reply(ZX_ERR_OUT_OF_RANGE);
}

// Fake device that exposes the thermal banjo protocol. Upon calling Connect, a new instance of
// FakeAmlThermal is created to serve a client, at which point any previous FakeThermalAml
// instance is destroyed.
class FakeThermalDevice : public ddk::ThermalProtocol<FakeThermalDevice, ddk::base_protocol> {
 public:
  FakeThermalDevice()
      : proto_({&thermal_protocol_ops_, this}), device_info_(kDefaultDeviceInfo), fidl_service_() {}

  zx_status_t ThermalConnect(zx::channel chan) {
    fidl_service_ = std::make_unique<FakeAmlThermal>();
    fidl_service_->set_device_info(device_info_);
    return fidl_service_->Init(fidl::ServerEnd<fuchsia_thermal::Device>(std::move(chan)));
  }

  const thermal_protocol_t* proto() const { return &proto_; }

  void set_device_info(const fuchsia_thermal::wire::ThermalDeviceInfo& device_info) {
    device_info_ = device_info;
  }

 private:
  thermal_protocol_t proto_;
  fuchsia_thermal::wire::ThermalDeviceInfo device_info_;
  std::unique_ptr<FakeAmlThermal> fidl_service_;
};

struct IncomingNamespace {
  fake_pdev::FakePDevFidl pdev_server;
  component::OutgoingDirectory outgoing{async_get_default_dispatcher()};
};

// Fixture that supports tests of AmlCpu::Create.
class AmlCpuBindingTest : public zxtest::Test {
 public:
  AmlCpuBindingTest() {
    root_ = MockDevice::FakeRootParent();

    ASSERT_OK(incoming_loop_.StartThread("incoming-ns-thread"));

    fake_pdev::FakePDevFidl::Config config;
    config.mmios[0] = mmio_.mmio();
    auto outgoing_endpoints = fidl::Endpoints<fuchsia_io::Directory>::Create();
    incoming_.SyncCall([config = std::move(config), server = std::move(outgoing_endpoints.server)](
                           IncomingNamespace* infra) mutable {
      infra->pdev_server.SetConfig(std::move(config));
      ASSERT_OK(infra->outgoing.AddService<fuchsia_hardware_platform_device::Service>(
          infra->pdev_server.GetInstanceHandler()));
      ASSERT_OK(infra->outgoing.Serve(std::move(server)));
    });
    ASSERT_NO_FATAL_FAILURE();
    root_->AddFidlService(fuchsia_hardware_platform_device::Service::Name,
                          std::move(outgoing_endpoints.client), "pdev");

    root_->AddProtocol(ZX_PROTOCOL_THERMAL, thermal_device_.proto()->ops,
                       thermal_device_.proto()->ctx, "thermal");

    root_->SetMetadata(DEVICE_METADATA_CLUSTER_SIZE_LEGACY, &kClusterSizeMetadata,
                       sizeof(kClusterSizeMetadata));
  }

 protected:
  std::shared_ptr<MockDevice> root_;
  async::Loop incoming_loop_{&kAsyncLoopConfigNoAttachToCurrentThread};
  async_patterns::TestDispatcherBound<IncomingNamespace> incoming_{incoming_loop_.dispatcher(),
                                                                   std::in_place};
  FakeMmio mmio_;
  FakeThermalDevice thermal_device_;
};

TEST_F(AmlCpuBindingTest, OneDomain) {
  ASSERT_OK(AmlCpu::Create(nullptr, root_.get()));
  ASSERT_EQ(root_->child_count(), 1);
}

TEST_F(AmlCpuBindingTest, TwoDomains) {
  // Set up device info that defines two power domains.
  thermal_device_.set_device_info([]() {
    fuchsia_thermal::wire::ThermalDeviceInfo result;

    result.active_cooling = false;
    result.passive_cooling = false;
    result.gpu_throttling = false;
    result.num_trip_points = 0;
    result.big_little = true;
    result.critical_temp_celsius = 0;

    result.opps[kLittleClusterIdx] = kFakeOperatingPoints;
    result.opps[kBigClusterIdx] = kFakeOperatingPoints;

    return result;
  }());

  ASSERT_OK(AmlCpu::Create(nullptr, root_.get()));
  ASSERT_EQ(root_->child_count(), 2);

  const auto& devices = root_->children();
  for (const auto& zxdev : devices) {
    AmlCpu* device = zxdev->GetDeviceContext<AmlCpu>();
    const size_t idx = device->PowerDomainIndex();

    // Find the cluster metadata that corresponds to this cluster index.
    const auto& cluster_size_meta_itr = std::find_if(
        std::begin(kClusterSizeMetadata), std::end(kClusterSizeMetadata),
        [idx](const legacy_cluster_size_t& elem) -> bool { return idx == elem.pd_id; });

    ASSERT_NE(cluster_size_meta_itr, std::end(kClusterSizeMetadata));
    ASSERT_EQ(cluster_size_meta_itr->core_count, device->ClusterCoreCount());
  }
}

class AmlCpuTest : public AmlCpu {
 public:
  AmlCpuTest(ThermalSyncClient thermal)
      : AmlCpu(nullptr, std::move(thermal), kBigClusterIdx, kBigClusterCoreCount) {}

  zx::vmo inspect_vmo() { return inspector_.DuplicateVmo(); }
};

using inspect::InspectTestHelper;

class AmlCpuTestFixture : public InspectTestHelper, public zxtest::Test {
 public:
  explicit AmlCpuTestFixture() : loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}
  void SetUp() override;

 protected:
  FakeAmlThermal thermal_;

  async::Loop loop_;
  std::unique_ptr<AmlCpuTest> dut_;
  CpuCtrlSyncClient cpu_client_;
};

void AmlCpuTestFixture::SetUp() {
  auto thermal_eps = fidl::Endpoints<fuchsia_thermal::Device>::Create();

  ASSERT_OK(thermal_.Init(std::move(thermal_eps.server)));
  ThermalSyncClient thermal_client = fidl::WireSyncClient(std::move(thermal_eps.client));

  dut_ = std::make_unique<AmlCpuTest>(std::move(thermal_client));

  auto cpu_eps = fidl::Endpoints<fuchsia_cpuctrl::Device>::Create();
  fidl::BindServer(loop_.dispatcher(), std::move(cpu_eps.server), dut_.get());
  loop_.StartThread("aml-cpu-legacy-test-thread");

  cpu_client_ = CpuCtrlSyncClient(std::move(cpu_eps.client));
}

TEST_F(AmlCpuTestFixture, TestGetOperatingPointInfo) {
  // Make sure that we can get information about all the supported opps.
  for (uint32_t i = 0; i < kFakeOperatingPoints.count; i++) {
    auto oppInfo = cpu_client_->GetOperatingPointInfo(i);

    // First, make sure there were no transport errors.
    ASSERT_OK(oppInfo.status());

    // Then make sure that the driver accepted the call.
    ASSERT_FALSE(oppInfo->is_error());

    // Then make sure that we're getting the accepted frequency and voltage values.
    EXPECT_EQ(oppInfo->value()->info.frequency_hz,
              kFakeOperatingPoints.opp[kFakeOperatingPoints.count - i - 1].freq_hz);
    EXPECT_EQ(oppInfo->value()->info.voltage_uv,
              kFakeOperatingPoints.opp[kFakeOperatingPoints.count - i - 1].volt_uv);
  }

  // Make sure that we can't get any information about opps that don't exist.
  for (uint32_t i = kFakeOperatingPoints.count; i < kFakeOperatingPoints.count + 10; i++) {
    auto oppInfo = cpu_client_->GetOperatingPointInfo(i);

    // Even if it's an unsupported opp, we still expect the transport to
    // deliver the message successfully.
    ASSERT_OK(oppInfo.status());

    // Make sure that the driver returns an error, however.
    EXPECT_TRUE(oppInfo->is_error());
  }
}

TEST_F(AmlCpuTestFixture, TestSetCurrentOperatingPoint) {
  // Make sure that we can drive the CPU to all of the supported operating
  // points.
  for (uint32_t i = 0; i < kFakeOperatingPoints.count; i++) {
    uint32_t out_state = UINT32_MAX;
    zx_status_t st = dut_->SetCurrentOperatingPointInternal(i, &out_state);

    // Make sure the call succeeded.
    EXPECT_OK(st);

    // Make sure we could actually drive the device into the state that we
    // expected.
    EXPECT_EQ(out_state, i);

    // Make sure that the call was forwarded to the thermal driver.
    const uint16_t kExpectedOperatingPoint =
        static_cast<uint16_t>(kFakeOperatingPoints.count - i - 1);
    EXPECT_EQ(kExpectedOperatingPoint, thermal_.ActiveOperatingPoint());
  }

  // Next make sure that we can't drive the CPU into any unsupported
  // operating points.
  for (uint32_t i = kFakeOperatingPoints.count; i < kFakeOperatingPoints.count + 10; i++) {
    const uint16_t kInitialOperatingPoint = thermal_.ActiveOperatingPoint();
    uint32_t out_state = UINT32_MAX;
    zx_status_t st = dut_->SetCurrentOperatingPointInternal(i, &out_state);

    // This is not a supported operating point.
    EXPECT_NOT_OK(st);

    // Make sure we haven't meddled with `out_state`
    EXPECT_EQ(out_state, UINT32_MAX);

    // Make sure we haven't meddled with the thermal driver's active
    // operating point.
    EXPECT_EQ(kInitialOperatingPoint, thermal_.ActiveOperatingPoint());
  }
}

TEST_F(AmlCpuTestFixture, TestSetCpuInfo) {
  uint32_t test_cpu_version = 0x28200b02;
  dut_->SetCpuInfo(test_cpu_version);
  ASSERT_NO_FATAL_FAILURE(ReadInspect(dut_->inspect_vmo()));
  auto* cpu_info = hierarchy().GetByPath({"cpu_info_service"});
  ASSERT_TRUE(cpu_info);

  // cpu_major_revision : 40
  ASSERT_NO_FATAL_FAILURE(
      CheckProperty(cpu_info->node(), "cpu_major_revision", inspect::UintPropertyValue(40)));
  // cpu_minor_revision : 11
  ASSERT_NO_FATAL_FAILURE(
      CheckProperty(cpu_info->node(), "cpu_minor_revision", inspect::UintPropertyValue(11)));
  // cpu_package_id : 2
  ASSERT_NO_FATAL_FAILURE(
      CheckProperty(cpu_info->node(), "cpu_package_id", inspect::UintPropertyValue(2)));
}

TEST_F(AmlCpuTestFixture, TestGetOperatingPointCount) {
  auto resp = cpu_client_->GetOperatingPointCount();

  ASSERT_OK(resp.status());

  EXPECT_EQ(resp.value()->count, kFakeOperatingPoints.count);
}

TEST_F(AmlCpuTestFixture, TestGetNumLogicalCores) {
  auto resp = cpu_client_->GetNumLogicalCores();

  ASSERT_OK(resp.status());

  EXPECT_EQ(resp.value().count, kBigClusterCoreCount);
}

}  // namespace amlogic_cpu
