/**
 * Copyright © 2024 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mock_pmbus.hpp"
#include "mock_services.hpp"
#include "pmbus.hpp"
#include "pmbus_driver_device.hpp"
#include "rail.hpp"
#include "services.hpp"

#include <errno.h>
#include <stdlib.h> // for mkdtemp()

#include <cstdint>
#include <exception>
#include <filesystem>
#include <format>
#include <fstream>
#include <map>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace phosphor::power::sequencer;
using namespace phosphor::pmbus;

using ::testing::Return;
using ::testing::Throw;

class PMBusDriverDeviceTests : public ::testing::Test
{
  protected:
    /**
     * Constructor.
     *
     * Creates a temporary directory to use in simulating sysfs files.
     */
    PMBusDriverDeviceTests() : ::testing::Test{}
    {
        char pathTemplate[] = "/tmp/pmbus_driver_device_testsXXXXXX";
        char* retVal = mkdtemp(pathTemplate);
        if (retVal == nullptr)
        {
            throw std::runtime_error{std::format(
                "Unable to create temporary directory: errno={}", errno)};
        }
        tempDir = fs::path{pathTemplate};
    }

    /**
     * Destructor.
     *
     * Deletes the temporary directory created in the constructor.
     */
    virtual ~PMBusDriverDeviceTests()
    {
        try
        {
            if (!tempDir.empty() && fs::exists(tempDir))
            {
                fs::remove_all(tempDir);
            }
        }
        catch (...)
        {
            // Destructors must not throw exceptions
        }
    }

    /**
     * Creates a Rail object that checks for a pgood fault using STATUS_VOUT.
     *
     * @param name Unique name for the rail
     * @param pageNum PMBus PAGE number of the rail
     * @return Rail object
     */
    std::unique_ptr<Rail> createRail(const std::string& name, uint8_t pageNum)
    {
        std::optional<std::string> presence{};
        std::optional<uint8_t> page{pageNum};
        bool isPowerSupplyRail{false};
        bool checkStatusVout{true};
        bool compareVoltageToLimit{false};
        std::optional<GPIO> gpio{};
        return std::make_unique<Rail>(name, presence, page, isPowerSupplyRail,
                                      checkStatusVout, compareVoltageToLimit,
                                      gpio);
    }

    /**
     * Creates a file with the specified contents within the temporary
     * directory.
     *
     * @param name File name
     * @param contents File contents
     */
    void createFile(const std::string& name, const std::string& contents = "")
    {
        fs::path path{tempDir / name};
        std::ofstream out{path};
        out << contents;
        out.close();
    }

    /**
     * Temporary directory that is used to create simulated sysfs / hmmon files.
     */
    fs::path tempDir{};
};

TEST_F(PMBusDriverDeviceTests, Constructor)
{
    // Test where works; optional parameters not specified
    {
        MockServices services;

        std::string name{"XYZ_PSEQ"};
        std::vector<std::unique_ptr<Rail>> rails;
        rails.emplace_back(createRail("VDD", 5));
        rails.emplace_back(createRail("VIO", 7));
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        EXPECT_EQ(device.getName(), name);
        EXPECT_EQ(device.getRails().size(), 2);
        EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
        EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
        EXPECT_EQ(device.getBus(), bus);
        EXPECT_EQ(device.getAddress(), address);
        EXPECT_EQ(device.getDriverName(), "");
        EXPECT_EQ(device.getInstance(), 0);
        EXPECT_NE(&(device.getPMBusInterface()), nullptr);
    }

    // Test where works; optional parameters specified
    {
        MockServices services;

        std::string name{"XYZ_PSEQ"};
        std::vector<std::unique_ptr<Rail>> rails;
        rails.emplace_back(createRail("VDD", 5));
        rails.emplace_back(createRail("VIO", 7));
        uint8_t bus{3};
        uint16_t address{0x72};
        std::string driverName{"xyzdev"};
        size_t instance{3};
        PMBusDriverDevice device{name,    std::move(rails), services, bus,
                                 address, driverName,       instance};

        EXPECT_EQ(device.getName(), name);
        EXPECT_EQ(device.getRails().size(), 2);
        EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
        EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
        EXPECT_EQ(device.getBus(), bus);
        EXPECT_EQ(device.getAddress(), address);
        EXPECT_EQ(device.getDriverName(), driverName);
        EXPECT_EQ(device.getInstance(), instance);
        EXPECT_NE(&(device.getPMBusInterface()), nullptr);
    }
}

TEST_F(PMBusDriverDeviceTests, GetBus)
{
    MockServices services;

    std::string name{"XYZ_PSEQ"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{4};
    uint16_t address{0x72};
    PMBusDriverDevice device{name, std::move(rails), services, bus, address};

    EXPECT_EQ(device.getBus(), bus);
}

TEST_F(PMBusDriverDeviceTests, GetAddress)
{
    MockServices services;

    std::string name{"XYZ_PSEQ"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{3};
    uint16_t address{0xab};
    PMBusDriverDevice device{name, std::move(rails), services, bus, address};

    EXPECT_EQ(device.getAddress(), address);
}

TEST_F(PMBusDriverDeviceTests, GetDriverName)
{
    MockServices services;

    std::string name{"XYZ_PSEQ"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{3};
    uint16_t address{0x72};
    std::string driverName{"xyzdev"};
    PMBusDriverDevice device{name, std::move(rails), services,
                             bus,  address,          driverName};

    EXPECT_EQ(device.getDriverName(), driverName);
}

TEST_F(PMBusDriverDeviceTests, GetInstance)
{
    MockServices services;

    std::string name{"XYZ_PSEQ"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{3};
    uint16_t address{0x72};
    std::string driverName{"xyzdev"};
    size_t instance{3};
    PMBusDriverDevice device{name,    std::move(rails), services, bus,
                             address, driverName,       instance};

    EXPECT_EQ(device.getInstance(), instance);
}

TEST_F(PMBusDriverDeviceTests, GetPMBusInterface)
{
    MockServices services;

    std::string name{"XYZ_PSEQ"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{3};
    uint16_t address{0x72};
    PMBusDriverDevice device{name, std::move(rails), services, bus, address};

    EXPECT_NE(&(device.getPMBusInterface()), nullptr);
}

TEST_F(PMBusDriverDeviceTests, GetGPIOValues)
{
    // Test where works
    {
        MockServices services;
        std::vector<int> gpioValues{1, 1, 1};
        EXPECT_CALL(services, getGPIOValues("abc_382%#, zy"))
            .Times(1)
            .WillOnce(Return(gpioValues));

        std::string name{"ABC_382%#, ZY"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        EXPECT_TRUE(device.getGPIOValues(services) == gpioValues);
    }

    // Test where fails with exception
    {
        MockServices services;
        EXPECT_CALL(services, getGPIOValues("xyz_pseq"))
            .Times(1)
            .WillOnce(
                Throw(std::runtime_error{"libgpiod: Unable to open chip"}));

        std::string name{"XYZ_PSEQ"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        try
        {
            device.getGPIOValues(services);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(e.what(),
                         "Unable to read GPIO values from device XYZ_PSEQ "
                         "using label xyz_pseq: "
                         "libgpiod: Unable to open chip");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, GetStatusWord)
{
    // Test where works
    {
        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, read("status13", Type::Debug, true))
            .Times(1)
            .WillOnce(Return(0x1234));

        uint8_t page{13};
        EXPECT_EQ(device.getStatusWord(page), 0x1234);
    }

    // Test where fails with exception
    {
        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, read("status0", Type::Debug, true))
            .Times(1)
            .WillOnce(Throw(std::runtime_error{"File does not exist"}));

        try
        {
            uint8_t page{0};
            device.getStatusWord(page);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to read STATUS_WORD for PAGE 0 of device xyz_pseq: "
                "File does not exist");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, GetStatusVout)
{
    // Test where works
    {
        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, read("status13_vout", Type::Debug, true))
            .Times(1)
            .WillOnce(Return(0xde));

        uint8_t page{13};
        EXPECT_EQ(device.getStatusVout(page), 0xde);
    }

    // Test where fails with exception
    {
        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, read("status0_vout", Type::Debug, true))
            .Times(1)
            .WillOnce(Throw(std::runtime_error{"File does not exist"}));

        try
        {
            uint8_t page{0};
            device.getStatusVout(page);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to read STATUS_VOUT for PAGE 0 of device xyz_pseq: "
                "File does not exist");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, GetReadVout)
{
    // Test where works
    {
        // Create simulated hwmon voltage label file
        createFile("in13_label"); // PAGE 9 -> file number 13

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout10")); // PAGE number 9 + 1
        EXPECT_CALL(pmbus, readString("in13_input", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("851"));

        uint8_t page{9};
        EXPECT_EQ(device.getReadVout(page), 0.851);
    }

    // Test where fails
    {
        // Create simulated hwmon voltage label file
        createFile("in13_label"); // PAGE 8 -> file number 13

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout9")); // PAGE number 8 + 1

        try
        {
            uint8_t page{9};
            device.getReadVout(page);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to read READ_VOUT for PAGE 9 of device xyz_pseq: "
                "Unable to find hwmon file number for PAGE 9 of device xyz_pseq");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, GetVoutUVFaultLimit)
{
    // Test where works
    {
        // Create simulated hwmon voltage label file
        createFile("in1_label"); // PAGE 6 -> file number 1

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout7")); // PAGE number 6 + 1
        EXPECT_CALL(pmbus, readString("in1_lcrit", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("1329"));

        uint8_t page{6};
        EXPECT_EQ(device.getVoutUVFaultLimit(page), 1.329);
    }

    // Test where fails
    {
        // Create simulated hwmon voltage label file
        createFile("in1_label"); // PAGE 7 -> file number 1

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout8")); // PAGE number 7 + 1

        try
        {
            uint8_t page{6};
            device.getVoutUVFaultLimit(page);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to read VOUT_UV_FAULT_LIMIT for PAGE 6 of device xyz_pseq: "
                "Unable to find hwmon file number for PAGE 6 of device xyz_pseq");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, GetPageToFileNumberMap)
{
    // Test where works: No voltage label files/mappings found
    {
        // Create simulated hwmon files.  None are valid voltage label files.
        createFile("in1_input");   // Not a label file
        createFile("in9_lcrit");   // Not a label file
        createFile("in_label");    // Invalid voltage label file name
        createFile("in9a_label");  // Invalid voltage label file name
        createFile("fan3_label");  // Not a voltage label file
        createFile("temp8_label"); // Not a voltage label file

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString).Times(0);

        const std::map<uint8_t, unsigned int>& map =
            device.getPageToFileNumberMap();
        EXPECT_TRUE(map.empty());
    }

    // Test where works: Multiple voltage label files/mappings found
    {
        // Create simulated hwmon files
        createFile("in9_label");   // PAGE 3 -> file number 9
        createFile("in13_label");  // PAGE 7 -> file number 13
        createFile("in0_label");   // PAGE 12 -> file number 0
        createFile("in11_label");  // No mapping; invalid contents
        createFile("in12_label");  // No mapping; invalid contents
        createFile("in1_input");   // Not a label file
        createFile("in7_lcrit");   // Not a label file
        createFile("fan3_label");  // Not a voltage label file
        createFile("temp8_label"); // Not a voltage label file

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in9_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout4")); // PAGE number 3 + 1
        EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout8")); // PAGE number 7 + 1
        EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout13")); // PAGE number 12 + 1
        EXPECT_CALL(pmbus, readString("in11_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout")); // Invalid format
        EXPECT_CALL(pmbus, readString("in12_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout13a")); // Invalid format

        const std::map<uint8_t, unsigned int>& map =
            device.getPageToFileNumberMap();
        EXPECT_EQ(map.size(), 3);
        EXPECT_EQ(map.at(uint8_t{3}), 9);
        EXPECT_EQ(map.at(uint8_t{7}), 13);
        EXPECT_EQ(map.at(uint8_t{12}), 0);
    }

    // Test where fails: hwmon directory path is actually a file
    {
        // Create file that will be returned as the hwmon directory path
        createFile("in9_label");

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir / "in9_label"));
        EXPECT_CALL(pmbus, readString).Times(0);

        const std::map<uint8_t, unsigned int>& map =
            device.getPageToFileNumberMap();
        EXPECT_TRUE(map.empty());
    }

    // Test where fails: hwmon directory path does not exist
    {
        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir / "does_not_exist"));
        EXPECT_CALL(pmbus, readString).Times(0);

        const std::map<uint8_t, unsigned int>& map =
            device.getPageToFileNumberMap();
        EXPECT_TRUE(map.empty());
    }

    // Test where fails: hwmon directory path is not readable
    {
        // Create simulated hwmon files
        createFile("in9_label");
        createFile("in13_label");
        createFile("in0_label");

        // Change temporary directory to be unreadable
        fs::permissions(tempDir, fs::perms::none);

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString).Times(0);

        try
        {
            device.getPageToFileNumberMap();
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            // Error message varies
        }

        // Change temporary directory to be readable/writable
        fs::permissions(tempDir, fs::perms::owner_all);
    }
}

TEST_F(PMBusDriverDeviceTests, GetFileNumber)
{
    // Test where works
    {
        // Create simulated hwmon voltage label files
        createFile("in0_label");  // PAGE 6 -> file number 0
        createFile("in13_label"); // PAGE 9 -> file number 13

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout7")); // PAGE number 6 + 1
        EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout10")); // PAGE number 9 + 1

        // Map was empty and needs to be built
        uint8_t page{6};
        EXPECT_EQ(device.getFileNumber(page), 0);

        // Map had already been built
        page = 9;
        EXPECT_EQ(device.getFileNumber(page), 13);
    }

    // Test where fails: No mapping for specified PMBus PAGE
    {
        // Create simulated hwmon voltage label files
        createFile("in0_label");  // PAGE 6 -> file number 0
        createFile("in13_label"); // PAGE 9 -> file number 13

        MockServices services;

        std::string name{"xyz_pseq"};
        std::vector<std::unique_ptr<Rail>> rails;
        uint8_t bus{3};
        uint16_t address{0x72};
        PMBusDriverDevice device{name, std::move(rails), services, bus,
                                 address};

        MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
        EXPECT_CALL(pmbus, getPath(Type::Hwmon))
            .Times(1)
            .WillOnce(Return(tempDir));
        EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout7")); // PAGE number 6 + 1
        EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
            .Times(1)
            .WillOnce(Return("vout10")); // PAGE number 9 + 1

        try
        {
            uint8_t page{13};
            device.getFileNumber(page);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to find hwmon file number for PAGE 13 of device xyz_pseq");
        }
    }
}

TEST_F(PMBusDriverDeviceTests, PrepareForPgoodFaultDetection)
{
    // This is a protected method and cannot be called directly from a gtest.
    // Call findPgoodFault() which calls prepareForPgoodFaultDetection().

    // Create simulated hwmon voltage label file
    createFile("in1_label"); // PAGE 6 -> file number 1

    MockServices services;
    std::vector<int> gpioValues{1, 1, 1};
    EXPECT_CALL(services, getGPIOValues("xyz_pseq"))
        .Times(1)
        .WillOnce(Return(gpioValues));

    std::string name{"xyz_pseq"};
    std::vector<std::unique_ptr<Rail>> rails;
    uint8_t bus{3};
    uint16_t address{0x72};
    PMBusDriverDevice device{name, std::move(rails), services, bus, address};

    // Methods that get hwmon file info should be called twice
    MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
    EXPECT_CALL(pmbus, getPath(Type::Hwmon))
        .Times(2)
        .WillRepeatedly(Return(tempDir));
    EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
        .Times(2)
        .WillRepeatedly(Return("vout7")); // PAGE number 6 + 1

    // Map was empty and needs to be built
    uint8_t page{6};
    EXPECT_EQ(device.getFileNumber(page), 1);

    // Call findPgoodFault() which calls prepareForPgoodFaultDetection() which
    // rebuilds the map.
    std::string powerSupplyError{};
    std::map<std::string, std::string> additionalData{};
    std::string error = device.findPgoodFault(services, powerSupplyError,
                                              additionalData);
    EXPECT_TRUE(error.empty());
    EXPECT_EQ(additionalData.size(), 0);

    EXPECT_EQ(device.getFileNumber(page), 1);
}
