// Copyright 2022 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 <lib/fpromise/result.h>
#include <lib/fpromise/single_threaded_executor.h>
#include <lib/inspect/cpp/inspector.h>
#include <lib/inspect/cpp/reader.h>

#include <gtest/gtest.h>

#include "src/graphics/display/drivers/intel-i915/dp-display.h"
#include "src/graphics/display/drivers/intel-i915/fake-dpcd-channel.h"

namespace i915 {

namespace {

using testing::FakeDpcdChannel;
using testing::kDefaultLaneCount;
using testing::kMaxLinkRateTableEntries;

TEST(DpCapabilitiesTest, NoSupportedLinkRates) {
  FakeDpcdChannel fake_dpcd;

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  EXPECT_TRUE(cap.is_error());
}

// Tests that invalid lane counts are rejected.
TEST(DpCapabilitiesTest, InvalidMaxLaneCount) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k1620Mbps);

  fake_dpcd.SetMaxLaneCount(0);
  EXPECT_TRUE(DpCapabilities::Read(&fake_dpcd).is_error());

  fake_dpcd.SetMaxLaneCount(3);
  EXPECT_TRUE(DpCapabilities::Read(&fake_dpcd).is_error());

  fake_dpcd.SetMaxLaneCount(5);
  EXPECT_TRUE(DpCapabilities::Read(&fake_dpcd).is_error());
}

// Tests that the basic set of getters work for non-EDP.
TEST(DpCapabilitiesTest, BasicFields) {
  FakeDpcdChannel fake_dpcd;

  fake_dpcd.SetDpcdRevision(dpcd::Revision::k1_4);
  fake_dpcd.SetMaxLaneCount(kDefaultLaneCount);
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k1620Mbps);
  fake_dpcd.SetSinkCount(1);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_EQ(dpcd::Revision::k1_4, cap.value().dpcd_revision());
  EXPECT_EQ(kDefaultLaneCount, cap.value().max_lane_count());
  EXPECT_EQ(1u, cap.value().sink_count());
  EXPECT_EQ(1u, cap.value().supported_link_rates_mbps().size());

  // eDP capabilities should be unavailable.
  EXPECT_EQ(std::nullopt, cap.value().edp_revision());
  EXPECT_FALSE(cap.value().backlight_aux_power());
  EXPECT_FALSE(cap.value().backlight_aux_brightness());
}

// Tests that eDP registers are processed when supported.
TEST(DpCapabilitiesTest, EdpRegisters) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_2);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_EQ(std::optional{dpcd::EdpRevision::k1_2}, cap.value().edp_revision());
  EXPECT_FALSE(cap.value().backlight_aux_power());
  EXPECT_FALSE(cap.value().backlight_aux_brightness());
}

TEST(DpCapabilitiesTest, EdpBacklight) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_2);

  dpcd::EdpGeneralCap1 gc;
  gc.set_tcon_backlight_adjustment_cap(1);
  gc.set_backlight_aux_enable_cap(1);
  fake_dpcd.registers[dpcd::DPCD_EDP_GENERAL_CAP1] = gc.reg_value();

  dpcd::EdpBacklightCap bc;
  bc.set_brightness_aux_set_cap(1);
  fake_dpcd.registers[dpcd::DPCD_EDP_BACKLIGHT_CAP] = bc.reg_value();

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_TRUE(cap.value().backlight_aux_power());
  EXPECT_TRUE(cap.value().backlight_aux_brightness());
}

// Tests that the list of supported link rates is populated correctly using the "Max Link Rate"
// method.
TEST(DpCapabilitiesTest, MaxLinkRate1620NoEdp) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k1620Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_FALSE(cap.value().use_link_rate_table());
  ASSERT_EQ(1u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(1620u, cap.value().supported_link_rates_mbps()[0]);
}

// Tests that the list of supported link rates is populated correctly using the "Max Link Rate"
// method.
TEST(DpCapabilitiesTest, MaxLinkRate2700NoEdp) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k2700Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_FALSE(cap.value().use_link_rate_table());
  ASSERT_EQ(2u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(1620u, cap.value().supported_link_rates_mbps()[0]);
  EXPECT_EQ(2700u, cap.value().supported_link_rates_mbps()[1]);
}

// Tests that the list of supported link rates is populated correctly using the "Max Link Rate"
// method.
TEST(DpCapabilitiesTest, MaxLinkRate5400NoEdp) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k5400Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_FALSE(cap.value().use_link_rate_table());
  ASSERT_EQ(3u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(1620u, cap.value().supported_link_rates_mbps()[0]);
  EXPECT_EQ(2700u, cap.value().supported_link_rates_mbps()[1]);
  EXPECT_EQ(5400u, cap.value().supported_link_rates_mbps()[2]);
}

// Tests that the list of supported link rates is populated correctly using the "Max Link Rate"
// method.
TEST(DpCapabilitiesTest, MaxLinkRate8100NoEdp) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k8100Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_FALSE(cap.value().use_link_rate_table());
  ASSERT_EQ(4u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(1620u, cap.value().supported_link_rates_mbps()[0]);
  EXPECT_EQ(2700u, cap.value().supported_link_rates_mbps()[1]);
  EXPECT_EQ(5400u, cap.value().supported_link_rates_mbps()[2]);
  EXPECT_EQ(8100u, cap.value().supported_link_rates_mbps()[3]);
}

// Tests that link rate discovery falls back to MAX_LINK_RATE if eDP v1.4 is supported but the
// link rate table is empty.
TEST(DpCapabilitiesTest, FallbackToMaxLinkRateWhenLinkRateTableIsEmpty) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k1620Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_FALSE(cap.value().use_link_rate_table());
  EXPECT_FALSE(cap.value().supported_link_rates_mbps().empty());
}

// Tests that the list of supported link rates is populated correctly when using the "Link Rate
// Table" method.
TEST(DpCapabilitiesTest, LinkRateTableOneEntry) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd.SetMaxLinkRate(0);  // Not supported

  fake_dpcd.PopulateLinkRateTable({100});  // 100 * 200kHz ==> 20MHz

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_TRUE(cap.value().use_link_rate_table());
  EXPECT_EQ(1u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(20u, cap.value().supported_link_rates_mbps()[0]);
}

// Tests that the list of supported link rates is populated correctly when using the "Link Rate
// Table" method.
TEST(DpCapabilitiesTest, LinkRateTableSomeEntries) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd.SetMaxLinkRate(0);  // Not supported

  // 100 * 200kHz ==> 20MHz
  // 200 * 200kHz ==> 40MHz
  // 300 * 200kHz ==> 60MHz
  fake_dpcd.PopulateLinkRateTable({100, 200, 300});

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_TRUE(cap.value().use_link_rate_table());
  EXPECT_EQ(3u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(std::vector<uint32_t>({20, 40, 60}), cap.value().supported_link_rates_mbps());
}

// Tests that the list of supported link rates is populated correctly when using the "Link Rate
// Table" method.
TEST(DpCapabilitiesTest, LinkRateTableMaxEntries) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd.SetMaxLinkRate(0);  // Not supported

  // Link rate table entries are stored in units of 200kHz (or kbps). The DpCapabilities data
  // structure stores them in units of Mbps. 1 Mbps = 5 * 200kbps.
  constexpr uint16_t kConversionFactor = 5;
  std::vector<uint16_t> input;
  std::vector<uint32_t> output;
  for (unsigned i = 1; i <= kMaxLinkRateTableEntries; i++) {
    input.push_back(static_cast<uint16_t>(kConversionFactor * i));
    output.push_back(i);
  }
  fake_dpcd.PopulateLinkRateTable(std::move(input));

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_TRUE(cap.value().use_link_rate_table());
  EXPECT_EQ(kMaxLinkRateTableEntries, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(output, cap.value().supported_link_rates_mbps());
}

// Tests that the list of supported link rates is populated based on the "Link Rate Table" method
// when both the table and the MAX_LINK_RATE register hold valid values (which is optional but
// allowed by the eDP specification).
TEST(DpCapabilitiesTest, LinkRateTableUsedWhenMaxLinkRateIsAlsoPresent) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k2700Mbps);

  // Link rate table entries are stored in units of 200kHz (or kbps). The DpCapabilities data
  // structure stores them in units of Mbps. 1 Mbps = 5 * 200kbps.
  constexpr uint16_t kConversionFactor = 5;
  constexpr uint32_t kExpectedLinkRate = 5400;
  fake_dpcd.PopulateLinkRateTable({kExpectedLinkRate * kConversionFactor});

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());
  EXPECT_TRUE(cap.value().use_link_rate_table());
  EXPECT_EQ(1u, cap.value().supported_link_rates_mbps().size());
  EXPECT_EQ(kExpectedLinkRate, cap.value().supported_link_rates_mbps()[0]);
}

// Tests that the DP capabilities can be inspected and the DP capability values
// are correctly propagated to the inspect node.
TEST(DpCapabilitiesTest, Inspect) {
  FakeDpcdChannel fake_dpcd;
  fake_dpcd.SetDefaults();
  fake_dpcd.SetMaxLinkRate(dpcd::LinkBw::k2700Mbps);

  const fpromise::result<DpCapabilities> cap = DpCapabilities::Read(&fake_dpcd);
  ASSERT_TRUE(cap.is_ok());

  inspect::Inspector inspector;
  cap.value().PublishToInspect(&inspector.GetRoot());

  fpromise::single_threaded_executor executor;
  executor.schedule_task(
      inspect::ReadFromInspector(inspector).then([&](fpromise::result<inspect::Hierarchy>& result) {
        ASSERT_TRUE(result.is_ok());
        auto& node = result.value().node();

        auto dpcd_revision = node.get_property<inspect::StringPropertyValue>("dpcd_revision");
        ASSERT_TRUE(dpcd_revision);
        EXPECT_STREQ("DPCD r1.4", dpcd_revision->value().c_str());

        auto edp_revision = node.get_property<inspect::StringPropertyValue>("edp_revision");
        ASSERT_TRUE(edp_revision);
        EXPECT_STREQ("not supported", edp_revision->value().c_str());

        auto sink_count = node.get_property<inspect::UintPropertyValue>("sink_count");
        ASSERT_TRUE(sink_count);
        EXPECT_EQ(testing::kDefaultSinkCount, sink_count->value());

        auto max_lane_count = node.get_property<inspect::UintPropertyValue>("max_lane_count");
        ASSERT_TRUE(max_lane_count);
        EXPECT_EQ(testing::kDefaultLaneCount, max_lane_count->value());

        auto supported_link_rates_list =
            node.get_property<inspect::UintArrayValue>("supported_link_rates_mbps_per_lane");
        ASSERT_TRUE(supported_link_rates_list);
        ASSERT_EQ(2u, supported_link_rates_list->value().size());
        EXPECT_EQ(1620u, supported_link_rates_list->value()[0]);
        EXPECT_EQ(2700u, supported_link_rates_list->value()[1]);
      }));
  executor.run();
}

}  // namespace

}  // namespace i915
