/**
 * 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 "standard_device.hpp"

#include "format_utils.hpp"

#include <exception>
#include <format>
#include <span>
#include <stdexcept>

namespace phosphor::power::sequencer
{

std::string StandardDevice::findPgoodFault(
    Services& services, const std::string& powerSupplyError,
    std::map<std::string, std::string>& additionalData)
{
    std::string error{};
    try
    {
        prepareForPgoodFaultDetection(services);

        // Get all GPIO values (if possible) from device.  They may be slow to
        // obtain, so obtain them once and then pass values to each Rail object.
        std::vector<int> gpioValues = getGPIOValuesIfPossible(services);

        // Loop through all the rails checking if any detected a pgood fault.
        // The rails are in power-on-sequence order.
        for (std::unique_ptr<Rail>& rail : rails)
        {
            if (rail->hasPgoodFault(*this, services, gpioValues,
                                    additionalData))
            {
                services.logErrorMsg(std::format(
                    "Pgood fault found in rail monitored by device {}", name));

                // If this is a PSU rail and a PSU error was previously detected
                if (rail->isPowerSupplyRail() && !powerSupplyError.empty())
                {
                    // Return power supply error as root cause
                    error = powerSupplyError;
                }
                else
                {
                    // Return pgood fault as root cause
                    error =
                        "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault";
                }

                storePgoodFaultDebugData(services, gpioValues, additionalData);
                break;
            }
        }
    }
    catch (const std::exception& e)
    {
        throw std::runtime_error{std::format(
            "Unable to determine if a pgood fault occurred in device {}: {}",
            name, e.what())};
    }
    return error;
}

std::vector<int> StandardDevice::getGPIOValuesIfPossible(Services& services)
{
    std::vector<int> values{};
    try
    {
        values = getGPIOValues(services);
    }
    catch (...)
    {}
    return values;
}

void StandardDevice::storePgoodFaultDebugData(
    Services& services, const std::vector<int>& gpioValues,
    std::map<std::string, std::string>& additionalData)
{
    try
    {
        additionalData.emplace("DEVICE_NAME", name);
        storeGPIOValues(services, gpioValues, additionalData);
    }
    catch (...)
    {}
}

void StandardDevice::storeGPIOValues(
    Services& services, const std::vector<int>& values,
    std::map<std::string, std::string>& additionalData)
{
    if (!values.empty())
    {
        std::string valuesStr = format_utils::toString(std::span(values));
        services.logInfoMsg(
            std::format("Device {} GPIO values: {}", name, valuesStr));
        additionalData.emplace("GPIO_VALUES", valuesStr);
    }
}

} // namespace phosphor::power::sequencer
