// Copyright 2020 The Chromium OS 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 "typecd/port.h"

#include <string>

#include <base/files/scoped_temp_dir.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "typecd/test_constants.h"
#include "typecd/test_utils.h"

namespace {
constexpr char kInvalidDataRole1[] = "xsadft [hasdr]";
constexpr char kInvalidDataRole2[] = "]asdf[ dsdd";
constexpr char kValidDataRole1[] = "device";
constexpr char kValidDataRole2[] = "[host] device";
constexpr char kValidDataRole3[] = "host [device]";
}  // namespace

namespace typecd {

class PortTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    temp_dir_ = scoped_temp_dir_.GetPath();
  }

 public:
  base::FilePath temp_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

// Check that basic Port creation, partner addition/deletion works.
TEST_F(PortTest, TestBasicAdd) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);
  EXPECT_NE(nullptr, port);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  EXPECT_NE(nullptr, port->partner_);
  port->RemovePartner();
  EXPECT_EQ(nullptr, port->partner_);
}

// Check GetDataRole() for various sysfs values.
TEST_F(PortTest, TestGetDataRole) {
  // Set up fake sysfs directory for the port..
  auto port_path = temp_dir_.Append("port0");
  ASSERT_TRUE(base::CreateDirectory(port_path));

  auto data_role_path = port_path.Append("data_role");
  ASSERT_TRUE(base::WriteFile(data_role_path, kValidDataRole1,
                              strlen(kValidDataRole1)));

  // Create a port.
  auto port = std::make_unique<Port>(base::FilePath(port_path), 0);
  ASSERT_NE(nullptr, port);

  EXPECT_EQ("device", port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(data_role_path, kValidDataRole2,
                              strlen(kValidDataRole2)));
  EXPECT_EQ("host", port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kValidDataRole3,
                              strlen(kValidDataRole3)));
  EXPECT_EQ("device", port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kInvalidDataRole1,
                              strlen(kInvalidDataRole1)));
  EXPECT_EQ("", port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kInvalidDataRole2,
                              strlen(kInvalidDataRole2)));
  EXPECT_EQ("", port->GetDataRole());
}

// Check that DP Alt Mode Entry checks work as expected for a true case:
TEST_F(PortTest, TestDPAltModeEntryCheckTrue) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));

  // Set up fake sysfs paths for 1 alt mode.
  // Set the number of alt modes supported.
  port->partner_->SetNumAltModes(1);

  // Add the DP alt mode.
  std::string mode0_dirname =
      base::StringPrintf("port%d-partner.%d", 0, kDPAltModeIndex);
  auto mode0_path = temp_dir_.Append(mode0_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode0_path, kDPAltModeSID, kDPVDO_WD19TB,
                                kDPVDOIndex_WD19TB));
  port->AddRemovePartnerAltMode(mode0_path, true);

  EXPECT_TRUE(port->CanEnterDPAltMode());
}

// Check that DP Alt Mode Entry checks work as expected for a specific false
// case: The Startech dock DP VDO doesn't advertise DFP_D, so we *shouldn't*
// enter DP alternate mode, despite it supporting the DP SID.
TEST_F(PortTest, TestDPAltModeEntryCheckFalseWithDPSID) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));

  // Set up fake sysfs paths for 2 alt modes.
  // Set the number of alt modes supported.
  port->partner_->SetNumAltModes(2);

  // Add the DP alt mode.
  std::string mode0_dirname =
      base::StringPrintf("port%d-partner.%d", 0, kDPAltModeIndex);
  auto mode0_path = temp_dir_.Append(mode0_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode0_path, kDPAltModeSID, kDPVDO, kDPVDOIndex));
  port->AddRemovePartnerAltMode(mode0_path, true);

  // Add the TBT alt mode.
  std::string mode1_dirname =
      base::StringPrintf("port%d-partner.%d", 0, kTBTAltModeIndex);
  auto mode1_path = temp_dir_.Append(mode1_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode1_path, kTBTAltModeVID, kTBTVDO, kTBTVDOIndex));
  port->AddRemovePartnerAltMode(mode1_path, true);

  EXPECT_FALSE(port->CanEnterDPAltMode());
}

// Check that DP Alt Mode Entry checks work as expected for false cases.
TEST_F(PortTest, TestDPAltModeEntryCheckFalse) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  port->partner_->SetNumAltModes(0);

  // Check the case where the partner doesn't support any alt modes.
  EXPECT_FALSE(port->CanEnterDPAltMode());

  port->partner_->SetNumAltModes(1);

  // Set up fake sysfs paths for 1 alt mode.
  // Add the TBT alt mode.
  std::string mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO, kTBTVDOIndex));
  port->AddRemovePartnerAltMode(mode_path, true);

  EXPECT_FALSE(port->CanEnterDPAltMode());
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// working case:
// - Startech.com TB3DK2DPW Alpine Ridge Dock.
// - StarTech Passive Cable 40 Gbps PD 2.0
TEST_F(PortTest, TestTBTCompatibilityModeEntryCheckTrueStartech) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Startech.com TB3DK2DPW Alpine Ridge Dock.
  port->partner_->SetPDRevision(PDRevision::k20);
  port->partner_->SetIdHeaderVDO(0xd4008087);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0);
  port->partner_->SetProductTypeVDO2(0);
  port->partner_->SetProductTypeVDO3(0);

  port->partner_->SetNumAltModes(1);
  // Set up fake sysfs paths for 1 alt mode.
  // Add the TBT alt mode.
  std::string mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO, 0));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  // StarTech Passive Cable 40 Gbps PD 2.0
  port->cable_->SetPDRevision(PDRevision::k20);
  port->cable_->SetIdHeaderVDO(0x1c0020c2);
  port->cable_->SetCertStatVDO(0x000000b6);
  port->cable_->SetProductVDO(0x00010310);
  port->cable_->SetProductTypeVDO1(0x11082052);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  EXPECT_TRUE(port->CanEnterTBTCompatibilityMode());
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// non-working case:
// - Startech.com TB3DK2DPW Alpine Ridge Dock.
// - Nekteck USB 2.0 cable (5A).
TEST_F(PortTest, TestTBTCompatibilityModeEntryCheckFalseStartech) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Startech.com TB3DK2DPW Alpine Ridge Dock.
  port->partner_->SetPDRevision(PDRevision::k20);
  port->partner_->SetIdHeaderVDO(0xd4008087);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0);
  port->partner_->SetProductTypeVDO2(0);
  port->partner_->SetProductTypeVDO3(0);

  port->partner_->SetNumAltModes(1);
  // Set up fake sysfs paths for 1 alt mode.
  // Add the TBT alt mode.
  std::string mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO, 0));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  // Nekteck USB 2.0 cable (5A).
  port->cable_->SetPDRevision(PDRevision::k30);
  port->cable_->SetIdHeaderVDO(0x18002e98);
  port->cable_->SetCertStatVDO(0x00001533);
  port->cable_->SetProductVDO(0x00010200);
  port->cable_->SetProductTypeVDO1(0xc1082040);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  EXPECT_FALSE(port->CanEnterTBTCompatibilityMode());
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// working case:
// - Dell WD19TB dock.
TEST_F(PortTest, TestTBTCompatibilityModeEntryCheckTrueWD19TB) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Dell WD19TB Titan Ridge Dock.
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c0041c3);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0xb0700712);
  port->partner_->SetProductTypeVDO1(0x0);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(4);
  // Set up fake sysfs paths for partner alt modes.
  // Add the TBT alt mode.
  std::string mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO, kTBTVDOIndex));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the DP alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_WD19TB, 0));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the Dell alt mode 1.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 2);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode_path, kDellSVID_WD19TB, kDell_WD19TB_VDO1, 0));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the Dell alt mode 2.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 3);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode_path, kDellSVID_WD19TB, kDell_WD19TB_VDO2, 1));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  // Dell's cable is captive.
  port->cable_->SetPDRevision(PDRevision::k30);
  port->cable_->SetIdHeaderVDO(0x1c00413c);
  port->cable_->SetCertStatVDO(0x0);
  port->cable_->SetProductVDO(0xb052000);
  port->cable_->SetProductTypeVDO1(0x110c2042);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  EXPECT_TRUE(port->CanEnterTBTCompatibilityMode());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Belkin TBT3 Passive Cable 40Gbps.
TEST_F(PortTest, TestUSB4EntryTrueGatkexPassiveTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Gatkex creek USB4 dock..
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c800000);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0xd00001b);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(2);
  // Set up fake sysfs paths for partner alt modes.

  // Add the DP alt mode.
  auto mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_GatkexCreek,
                                kDPVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the TBT alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO_GatkexCreek,
                                kTBTVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  port->cable_->SetPDRevision(PDRevision::k30);
  port->cable_->SetIdHeaderVDO(0x1c002b1d);
  port->cable_->SetCertStatVDO(0x0);
  port->cable_->SetProductVDO(0x150c0001);
  port->cable_->SetProductTypeVDO1(0x11082042);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  port->cable_->SetNumAltModes(1);

  // Set up fake sysfs paths for cable alt modes.
  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 0);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, 0x30001, 0));
  port->AddCableAltMode(mode_path);

  EXPECT_TRUE(port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Hongju Full USB 3.1 Gen 1 5A passive cable..
TEST_F(PortTest, TestUSB4EntryTrueGatkexPassiveNonTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Gatkex creek USB4 dock..
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c800000);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0xd00001b);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(2);
  // Set up fake sysfs paths for partner alt modes.

  // Add the DP alt mode.
  auto mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_GatkexCreek,
                                kDPVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the TBT alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO_GatkexCreek,
                                kTBTVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  port->cable_->SetPDRevision(PDRevision::k20);
  port->cable_->SetIdHeaderVDO(0x18005694);
  port->cable_->SetCertStatVDO(0x88);
  port->cable_->SetProductVDO(0xce901a0);
  port->cable_->SetProductTypeVDO1(0x84051);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  port->cable_->SetNumAltModes(0);

  EXPECT_TRUE(port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// non-working case:
// - Intel Gatkex Creek USB4 dock.
// - Nekteck USB 2.0 5A Passive Cable.
TEST_F(PortTest, TestUSB4EntryFalseGatkexPassiveNonTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Gatkex creek USB4 dock..
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c800000);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0xd00001b);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(2);
  // Set up fake sysfs paths for partner alt modes.

  // Add the DP alt mode.
  auto mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_GatkexCreek,
                                kDPVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the TBT alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO_GatkexCreek,
                                kTBTVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  port->cable_->SetPDRevision(PDRevision::k30);
  port->cable_->SetIdHeaderVDO(0x18002e98);
  port->cable_->SetCertStatVDO(0x1533);
  port->cable_->SetProductVDO(0x10200);
  port->cable_->SetProductTypeVDO1(0xc1082040);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  port->cable_->SetNumAltModes(0);

  EXPECT_FALSE(port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// non-working case:
// - Intel Gatkex Creek USB4 dock.
// - Belkin TBT3 Active Cable 40Gbps.
//
// NOTE: This case is interesting because the TBT3 cable fails as it doesn't
// support Rounded Data rates.
TEST_F(PortTest, TestUSB4EntryFalseGatkexActiveTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Gatkex creek USB4 dock..
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c800000);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0xd00001b);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(2);
  // Set up fake sysfs paths for partner alt modes.

  // Add the DP alt mode.
  auto mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_GatkexCreek,
                                kDPVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the TBT alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO_GatkexCreek,
                                kTBTVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  port->cable_->SetPDRevision(PDRevision::k20);
  port->cable_->SetIdHeaderVDO(0x240020c2);
  port->cable_->SetCertStatVDO(0x0);
  port->cable_->SetProductVDO(0x40010);
  port->cable_->SetProductTypeVDO1(0x21085858);
  port->cable_->SetProductTypeVDO2(0x0);
  port->cable_->SetProductTypeVDO3(0x0);

  port->cable_->SetNumAltModes(2);

  // Set up fake sysfs paths for cable alt modes.
  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 0);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, 0x430001, 0));
  port->AddCableAltMode(mode_path);

  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, 0x04b4, 0x1, 0));
  port->AddCableAltMode(mode_path);

  EXPECT_FALSE(port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Apple Thunderbolt 3 Pro Cable.
TEST_F(PortTest, TestUSB4EntryTrueGatkexAppleTBT3ProCable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  // PD ID VDOs for the Gatkex creek USB4 dock..
  port->partner_->SetPDRevision(PDRevision::k30);
  port->partner_->SetIdHeaderVDO(0x4c800000);
  port->partner_->SetCertStatVDO(0x0);
  port->partner_->SetProductVDO(0x0);
  port->partner_->SetProductTypeVDO1(0xd00001b);
  port->partner_->SetProductTypeVDO2(0x0);
  port->partner_->SetProductTypeVDO3(0x0);

  port->partner_->SetNumAltModes(2);
  // Set up fake sysfs paths for partner alt modes.

  // Add the DP alt mode.
  auto mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, kDPVDO_GatkexCreek,
                                kDPVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Add the TBT alt mode.
  mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO_GatkexCreek,
                                kTBTVDOIndex_GatkexCreek));
  port->AddRemovePartnerAltMode(mode_path, true);

  // Set up fake sysfs paths and add a cable.
  port->AddCable(base::FilePath(kFakePort0CableSysPath));

  port->cable_->SetPDRevision(PDRevision::k30);
  port->cable_->SetIdHeaderVDO(0x240005ac);
  port->cable_->SetCertStatVDO(0x0);
  port->cable_->SetProductVDO(0x72043002);
  port->cable_->SetProductTypeVDO1(0x434858da);
  port->cable_->SetProductTypeVDO2(0x5a5f0001);
  port->cable_->SetProductTypeVDO3(0x0);

  port->cable_->SetNumAltModes(5);

  // Set up fake sysfs paths for cable alt modes.
  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 0);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kTBTAltModeVID, 0x00cb0001, 0));
  port->AddCableAltMode(mode_path);

  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 1);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, kDPAltModeSID, 0x000c0c0c, 0));
  port->AddCableAltMode(mode_path);

  // Apple alt modes.
  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 2);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, 0x05ac, 0x00000005, 0));
  port->AddCableAltMode(mode_path);

  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 3);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, 0x05ac, 0x00000007, 1));
  port->AddCableAltMode(mode_path);

  mode_dirname = base::StringPrintf("port%d-plug0.%d", 0, 4);
  mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode_path, 0x05ac, 0x00000002, 2));
  port->AddCableAltMode(mode_path);

  EXPECT_TRUE(port->CanEnterUSB4());
}

}  // namespace typecd
