// 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 "as370-thermal.h"

#include <fuchsia/hardware/thermal/c/fidl.h>
#include <lib/fake_ddk/fidl-helper.h>

#include <fbl/algorithm.h>
#include <mock-mmio-reg/mock-mmio-reg.h>
#include <mock/ddktl/protocol/clock.h>
#include <mock/ddktl/protocol/power.h>
#include <zxtest/zxtest.h>

namespace {

bool FloatNear(float a, float b) { return std::abs(a - b) < 0.001f; }

}  // namespace

namespace thermal {

using ThermalClient = llcpp::fuchsia::hardware::thermal::Device::SyncClient;
using llcpp::fuchsia::hardware::thermal::OperatingPoint;
using llcpp::fuchsia::hardware::thermal::OperatingPointEntry;
using llcpp::fuchsia::hardware::thermal::PowerDomain;
using llcpp::fuchsia::hardware::thermal::ThermalDeviceInfo;

class As370ThermalTest : public zxtest::Test {
 public:
  As370ThermalTest()
      : reg_region_(reg_array_, sizeof(uint32_t), std::size(reg_array_)),
        dut_(nullptr, ddk::MmioBuffer(reg_region_.GetMmioBuffer()), kThermalDeviceInfo,
             ddk::ClockProtocolClient(clock_.GetProto()),
             ddk::PowerProtocolClient(power_.GetProto())) {}

  void SetUp() override {
    ASSERT_OK(messenger_.SetMessageOp(
        &dut_, [](void* ctx, fidl_incoming_msg_t* msg, fidl_txn_t* txn) -> zx_status_t {
          return static_cast<As370Thermal*>(ctx)->DdkMessage(msg, txn);
        }));
  }

 protected:
  void VerifyAll() {
    ASSERT_NO_FATAL_FAILURES(clock_.VerifyAndClear());
    ASSERT_NO_FATAL_FAILURES(power_.VerifyAndClear());
  }

  fake_ddk::FidlMessenger messenger_;
  ddk_mock::MockMmioRegRegion reg_region_;
  ddk::MockClock clock_;
  ddk::MockPower power_;
  As370Thermal dut_;

 private:
  static constexpr ThermalDeviceInfo kThermalDeviceInfo = {
      .active_cooling = false,
      .passive_cooling = true,
      .gpu_throttling = false,
      .num_trip_points = 0,
      .big_little = false,
      .critical_temp_celsius = 0.0f,
      .trip_point_info = {},
      .opps =
          fidl::Array<OperatingPoint, 2>{
              OperatingPoint{
                  .opp =
                      fidl::Array<OperatingPointEntry, 16>{
                          // clang-format off
                          OperatingPointEntry{.freq_hz =   400'000'000, .volt_uv = 825'000},
                          OperatingPointEntry{.freq_hz =   800'000'000, .volt_uv = 825'000},
                          OperatingPointEntry{.freq_hz = 1'200'000'000, .volt_uv = 825'000},
                          OperatingPointEntry{.freq_hz = 1'400'000'000, .volt_uv = 825'000},
                          OperatingPointEntry{.freq_hz = 1'500'000'000, .volt_uv = 900'000},
                          OperatingPointEntry{.freq_hz = 1'800'000'000, .volt_uv = 900'000},
                          // clang-format on
                      },
                  .latency = 0,
                  .count = 6,
              },
              {
                  .opp = {},
                  .latency = 0,
                  .count = 0,
              },
          },
  };

  ddk_mock::MockMmioReg reg_array_[8];
};

TEST_F(As370ThermalTest, GetTemperature) {
  ThermalClient client(std::move(messenger_.local()));

  {
    reg_region_[0x14].ReadReturns(0x17ff);
    auto result = client.GetTemperatureCelsius();
    EXPECT_OK(result->status);
    EXPECT_TRUE(FloatNear(result->temp, 40.314f));
  }

  {
    reg_region_[0x14].ReadReturns(0x182b);
    auto result = client.GetTemperatureCelsius();
    EXPECT_OK(result->status);
    EXPECT_TRUE(FloatNear(result->temp, 43.019f));
  }
}

TEST_F(As370ThermalTest, DvfsOperatingPoint) {
  ThermalClient client(std::move(messenger_.local()));

  {
    // Success, sets operating point 0.
    power_.ExpectRequestVoltage(ZX_OK, 825'000, 825'000);
    clock_.ExpectSetRate(ZX_OK, 400'000'000);
    auto set_result = client.SetDvfsOperatingPoint(0, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 0);
  }

  {
    // Failure, unable to set exact voltage.
    power_.ExpectRequestVoltage(ZX_OK, 825'000, 900'000);
    auto set_result = client.SetDvfsOperatingPoint(2, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_NOT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 0);
  }

  {
    // Failure, unable to set frequency.
    power_.ExpectRequestVoltage(ZX_OK, 825'000, 825'000);
    clock_.ExpectSetRate(ZX_ERR_IO, 1'200'000'000);
    auto set_result = client.SetDvfsOperatingPoint(2, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_NOT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 0);
  }

  {
    // Success, sets operating point 4.
    power_.ExpectRequestVoltage(ZX_OK, 900'000, 900'000);
    clock_.ExpectSetRate(ZX_OK, 1'500'000'000);
    auto set_result = client.SetDvfsOperatingPoint(4, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 4);
  }

  {
    // Failure, unable to set frequency.
    clock_.ExpectSetRate(ZX_ERR_IO, 800'000'000);
    auto set_result = client.SetDvfsOperatingPoint(1, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_NOT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 4);
  }

  {
    // Failure, unable to set voltage.
    clock_.ExpectSetRate(ZX_OK, 800'000'000);
    power_.ExpectRequestVoltage(ZX_ERR_IO, 825'000, 0);
    auto set_result = client.SetDvfsOperatingPoint(1, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_NOT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 4);
  }

  {
    // Success, sets operating point 1.
    clock_.ExpectSetRate(ZX_OK, 800'000'000);
    power_.ExpectRequestVoltage(ZX_OK, 825'000, 825'000);
    auto set_result = client.SetDvfsOperatingPoint(1, PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(set_result->status);
    ASSERT_NO_FATAL_FAILURES(VerifyAll());
  }

  {
    auto get_result = client.GetDvfsOperatingPoint(PowerDomain::BIG_CLUSTER_POWER_DOMAIN);
    EXPECT_OK(get_result->status);
    EXPECT_EQ(get_result->op_idx, 1);
  }
}

TEST_F(As370ThermalTest, Init) {
  power_.ExpectRegisterPowerDomain(ZX_OK, 825'000, 900'000);
  power_.ExpectRequestVoltage(ZX_OK, 900'000, 900'000);
  clock_.ExpectSetRate(ZX_OK, 1'800'000'000);
  EXPECT_OK(dut_.Init());
  ASSERT_NO_FATAL_FAILURES(VerifyAll());
}

}  // namespace thermal
