/**
 * 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_services.hpp"
#include "rail.hpp"
#include "services.hpp"
#include "standard_device.hpp"

#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

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

using namespace phosphor::power::sequencer;

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

/**
 * @class StandardDeviceImpl
 *
 * Concrete subclass of the StandardDevice abstract class.
 *
 * This subclass is required for two reasons:
 * - StandardDevice has some pure virtual methods so it cannot be instantiated.
 * - The pure virtual methods provide the PMBus and GPIO information.  Mocking
 *   these makes it possible to test the pgood fault detection algorithm.
 *
 * This class is not intended to be used outside of this file.  It is
 * implementation detail for testing the the StandardDevice class.
 */
class StandardDeviceImpl : public StandardDevice
{
  public:
    // Specify which compiler-generated methods we want
    StandardDeviceImpl() = delete;
    StandardDeviceImpl(const StandardDeviceImpl&) = delete;
    StandardDeviceImpl(StandardDeviceImpl&&) = delete;
    StandardDeviceImpl& operator=(const StandardDeviceImpl&) = delete;
    StandardDeviceImpl& operator=(StandardDeviceImpl&&) = delete;
    virtual ~StandardDeviceImpl() = default;

    // Constructor just calls StandardDevice constructor
    explicit StandardDeviceImpl(const std::string& name,
                                std::vector<std::unique_ptr<Rail>> rails) :
        StandardDevice(name, std::move(rails))
    {}

    // Mock pure virtual methods
    MOCK_METHOD(std::vector<int>, getGPIOValues, (Services & services),
                (override));
    MOCK_METHOD(uint16_t, getStatusWord, (uint8_t page), (override));
    MOCK_METHOD(uint8_t, getStatusVout, (uint8_t page), (override));
    MOCK_METHOD(double, getReadVout, (uint8_t page), (override));
    MOCK_METHOD(double, getVoutUVFaultLimit, (uint8_t page), (override));
};

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

/**
 * Creates a Rail object that checks for a pgood fault using a GPIO.
 *
 * @param name Unique name for the rail
 * @param isPowerSupplyRail Specifies whether the rail is produced by a
                            power supply
 * @param gpio GPIO line to read to determine the pgood status of the rail
 * @return Rail object
 */
std::unique_ptr<Rail> createRailGPIO(const std::string& name,
                                     bool isPowerSupplyRail,
                                     unsigned int gpioLine)
{
    std::optional<std::string> presence{};
    std::optional<uint8_t> page{};
    bool checkStatusVout{false};
    bool compareVoltageToLimit{false};
    bool activeLow{false};
    std::optional<GPIO> gpio{GPIO{gpioLine, activeLow}};
    return std::make_unique<Rail>(name, presence, page, isPowerSupplyRail,
                                  checkStatusVout, compareVoltageToLimit, gpio);
}

TEST(StandardDeviceTests, Constructor)
{
    // Empty vector of rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        StandardDeviceImpl device{"xyz_pseq", std::move(rails)};

        EXPECT_EQ(device.getName(), "xyz_pseq");
        EXPECT_TRUE(device.getRails().empty());
    }

    // Non-empty vector of rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 3));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        EXPECT_EQ(device.getName(), "abc_pseq");
        EXPECT_EQ(device.getRails().size(), 3);
        EXPECT_EQ(device.getRails()[0]->getName(), "PSU");
        EXPECT_EQ(device.getRails()[1]->getName(), "VDD");
        EXPECT_EQ(device.getRails()[2]->getName(), "VIO");
    }
}

TEST(StandardDeviceTests, GetName)
{
    std::vector<std::unique_ptr<Rail>> rails{};
    StandardDeviceImpl device{"xyz_pseq", std::move(rails)};

    EXPECT_EQ(device.getName(), "xyz_pseq");
}

TEST(StandardDeviceTests, GetRails)
{
    // Empty vector of rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        StandardDeviceImpl device{"xyz_pseq", std::move(rails)};

        EXPECT_TRUE(device.getRails().empty());
    }

    // Non-empty vector of rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 3));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        EXPECT_EQ(device.getRails().size(), 3);
        EXPECT_EQ(device.getRails()[0]->getName(), "PSU");
        EXPECT_EQ(device.getRails()[1]->getName(), "VDD");
        EXPECT_EQ(device.getRails()[2]->getName(), "VIO");
    }
}

TEST(StandardDeviceTests, FindPgoodFault)
{
    // No rail has a pgood fault
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 2));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{1, 1, 1};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout(5)).Times(1).WillOnce(Return(0x00));
        EXPECT_CALL(device, getStatusVout(7)).Times(1).WillOnce(Return(0x00));

        MockServices services{};

        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);
    }

    // First rail has a pgood fault
    // Is a PSU rail: No PSU error specified
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 2));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{1, 1, 0};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout).Times(0);

        MockServices services{};
        EXPECT_CALL(services,
                    logInfoMsg("Device abc_pseq GPIO values: [1, 1, 0]"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Pgood fault found in rail monitored by device abc_pseq"))
            .Times(1);
        EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail PSU"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Rail PSU pgood GPIO line offset 2 has inactive value 0"))
            .Times(1);

        std::string powerSupplyError{};
        std::map<std::string, std::string> additionalData{};
        std::string error = device.findPgoodFault(services, powerSupplyError,
                                                  additionalData);
        EXPECT_EQ(error,
                  "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault");
        EXPECT_EQ(additionalData.size(), 5);
        EXPECT_EQ(additionalData["DEVICE_NAME"], "abc_pseq");
        EXPECT_EQ(additionalData["GPIO_VALUES"], "[1, 1, 0]");
        EXPECT_EQ(additionalData["RAIL_NAME"], "PSU");
        EXPECT_EQ(additionalData["GPIO_LINE"], "2");
        EXPECT_EQ(additionalData["GPIO_VALUE"], "0");
    }

    // First rail has a pgood fault
    // Is a PSU rail: PSU error specified
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 2));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{1, 1, 0};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout).Times(0);

        MockServices services{};
        EXPECT_CALL(services,
                    logInfoMsg("Device abc_pseq GPIO values: [1, 1, 0]"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Pgood fault found in rail monitored by device abc_pseq"))
            .Times(1);
        EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail PSU"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Rail PSU pgood GPIO line offset 2 has inactive value 0"))
            .Times(1);

        std::string powerSupplyError{"Undervoltage fault: PSU1"};
        std::map<std::string, std::string> additionalData{};
        std::string error = device.findPgoodFault(services, powerSupplyError,
                                                  additionalData);
        EXPECT_EQ(error, powerSupplyError);
        EXPECT_EQ(additionalData.size(), 5);
        EXPECT_EQ(additionalData["DEVICE_NAME"], "abc_pseq");
        EXPECT_EQ(additionalData["GPIO_VALUES"], "[1, 1, 0]");
        EXPECT_EQ(additionalData["RAIL_NAME"], "PSU");
        EXPECT_EQ(additionalData["GPIO_LINE"], "2");
        EXPECT_EQ(additionalData["GPIO_VALUE"], "0");
    }

    // Middle rail has a pgood fault
    // Not a PSU rail: PSU error specified
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 2));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{1, 1, 1};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout(5)).Times(1).WillOnce(Return(0x10));
        EXPECT_CALL(device, getStatusVout(7)).Times(0);
        EXPECT_CALL(device, getStatusWord(5)).Times(1).WillOnce(Return(0xbeef));

        MockServices services{};
        EXPECT_CALL(services,
                    logInfoMsg("Device abc_pseq GPIO values: [1, 1, 1]"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Pgood fault found in rail monitored by device abc_pseq"))
            .Times(1);
        EXPECT_CALL(services, logInfoMsg("Rail VDD STATUS_WORD: 0xbeef"))
            .Times(1);
        EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg("Rail VDD has fault bits set in STATUS_VOUT: 0x10"))
            .Times(1);

        std::string powerSupplyError{"Undervoltage fault: PSU1"};
        std::map<std::string, std::string> additionalData{};
        std::string error = device.findPgoodFault(services, powerSupplyError,
                                                  additionalData);
        EXPECT_EQ(error,
                  "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault");
        EXPECT_EQ(additionalData.size(), 5);
        EXPECT_EQ(additionalData["DEVICE_NAME"], "abc_pseq");
        EXPECT_EQ(additionalData["GPIO_VALUES"], "[1, 1, 1]");
        EXPECT_EQ(additionalData["RAIL_NAME"], "VDD");
        EXPECT_EQ(additionalData["STATUS_VOUT"], "0x10");
        EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
    }

    // Last rail has a pgood fault
    // Device returns 0 GPIO values
    // Does not halt pgood fault detection because GPIO values not used by rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailStatusVout("PSU", true, 3));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x00));
        EXPECT_CALL(device, getStatusVout(5)).Times(1).WillOnce(Return(0x00));
        EXPECT_CALL(device, getStatusVout(7)).Times(1).WillOnce(Return(0x11));
        EXPECT_CALL(device, getStatusWord(7)).Times(1).WillOnce(Return(0xbeef));

        MockServices services{};
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Pgood fault found in rail monitored by device abc_pseq"))
            .Times(1);
        EXPECT_CALL(services, logInfoMsg("Rail VIO STATUS_WORD: 0xbeef"))
            .Times(1);
        EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VIO"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg("Rail VIO has fault bits set in STATUS_VOUT: 0x11"))
            .Times(1);

        std::string powerSupplyError{};
        std::map<std::string, std::string> additionalData{};
        std::string error = device.findPgoodFault(services, powerSupplyError,
                                                  additionalData);
        EXPECT_EQ(error,
                  "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault");
        EXPECT_EQ(additionalData.size(), 4);
        EXPECT_EQ(additionalData["DEVICE_NAME"], "abc_pseq");
        EXPECT_EQ(additionalData["RAIL_NAME"], "VIO");
        EXPECT_EQ(additionalData["STATUS_VOUT"], "0x11");
        EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
    }

    // Last rail has a pgood fault
    // Exception occurs trying to obtain GPIO values from device
    // Does not halt pgood fault detection because GPIO values not used by rails
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailStatusVout("PSU", true, 3));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Throw(std::runtime_error{"Unable to acquire GPIO line"}));
        EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x00));
        EXPECT_CALL(device, getStatusVout(5)).Times(1).WillOnce(Return(0x00));
        EXPECT_CALL(device, getStatusVout(7)).Times(1).WillOnce(Return(0x11));
        EXPECT_CALL(device, getStatusWord(7)).Times(1).WillOnce(Return(0xbeef));

        MockServices services{};
        EXPECT_CALL(
            services,
            logErrorMsg(
                "Pgood fault found in rail monitored by device abc_pseq"))
            .Times(1);
        EXPECT_CALL(services, logInfoMsg("Rail VIO STATUS_WORD: 0xbeef"))
            .Times(1);
        EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VIO"))
            .Times(1);
        EXPECT_CALL(
            services,
            logErrorMsg("Rail VIO has fault bits set in STATUS_VOUT: 0x11"))
            .Times(1);

        std::string powerSupplyError{};
        std::map<std::string, std::string> additionalData{};
        std::string error = device.findPgoodFault(services, powerSupplyError,
                                                  additionalData);
        EXPECT_EQ(error,
                  "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault");
        EXPECT_EQ(additionalData.size(), 4);
        EXPECT_EQ(additionalData["DEVICE_NAME"], "abc_pseq");
        EXPECT_EQ(additionalData["RAIL_NAME"], "VIO");
        EXPECT_EQ(additionalData["STATUS_VOUT"], "0x11");
        EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
    }

    // Exception is thrown during pgood fault detection
    {
        std::vector<std::unique_ptr<Rail>> rails{};
        rails.emplace_back(createRailGPIO("PSU", true, 2));
        rails.emplace_back(createRailStatusVout("VDD", false, 5));
        rails.emplace_back(createRailStatusVout("VIO", false, 7));
        StandardDeviceImpl device{"abc_pseq", std::move(rails)};

        std::vector<int> gpioValues{1, 1, 1};
        EXPECT_CALL(device, getGPIOValues)
            .Times(1)
            .WillOnce(Return(gpioValues));
        EXPECT_CALL(device, getStatusVout(5))
            .Times(1)
            .WillOnce(Throw(std::runtime_error{"File does not exist"}));
        EXPECT_CALL(device, getStatusVout(7)).Times(0);

        MockServices services{};

        std::string powerSupplyError{};
        std::map<std::string, std::string> additionalData{};
        try
        {
            device.findPgoodFault(services, powerSupplyError, additionalData);
            ADD_FAILURE() << "Should not have reached this line.";
        }
        catch (const std::exception& e)
        {
            EXPECT_STREQ(
                e.what(),
                "Unable to determine if a pgood fault occurred in device abc_pseq: "
                "Unable to read STATUS_VOUT value for rail VDD: "
                "File does not exist");
        }
    }
}
