/**
 * Copyright © 2021 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 "ucd90320_monitor.hpp"

#include "types.hpp"
#include "utility.hpp"

#include <fmt/format.h>
#include <fmt/ranges.h>

#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Common/Device/error.hpp>

#include <chrono>
#include <fstream>
#include <map>
#include <span>
#include <string>

namespace phosphor::power::sequencer
{

using json = nlohmann::json;
using namespace pmbus;
using namespace phosphor::logging;
using namespace phosphor::power;

const std::string compatibleInterface =
    "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
const std::string compatibleNamesProperty = "Names";

namespace device_error = sdbusplus::xyz::openbmc_project::Common::Device::Error;

UCD90320Monitor::UCD90320Monitor(sdbusplus::bus::bus& bus, std::uint8_t i2cBus,
                                 std::uint16_t i2cAddress) :
    PowerSequencerMonitor(bus),
    match{bus,
          sdbusplus::bus::match::rules::interfacesAdded() +
              sdbusplus::bus::match::rules::sender(
                  "xyz.openbmc_project.EntityManager"),
          std::bind(&UCD90320Monitor::interfacesAddedHandler, this,
                    std::placeholders::_1)},
    pmbusInterface{
        fmt::format("/sys/bus/i2c/devices/{}-{:04x}", i2cBus, i2cAddress)
            .c_str(),
        "ucd9000", 0}

{
    // Use the compatible system types information, if already available, to
    // load the configuration file
    findCompatibleSystemTypes();
}

void UCD90320Monitor::findCompatibleSystemTypes()
{
    try
    {
        auto subTree = util::getSubTree(bus, "/xyz/openbmc_project/inventory",
                                        compatibleInterface, 0);

        auto objectIt = subTree.cbegin();
        if (objectIt != subTree.cend())
        {
            const auto& objPath = objectIt->first;

            // Get the first service name
            auto serviceIt = objectIt->second.cbegin();
            if (serviceIt != objectIt->second.cend())
            {
                std::string service = serviceIt->first;
                if (!service.empty())
                {
                    std::vector<std::string> compatibleSystemTypes;

                    // Get compatible system types property value
                    util::getProperty(compatibleInterface,
                                      compatibleNamesProperty, objPath, service,
                                      bus, compatibleSystemTypes);

                    log<level::DEBUG>(
                        fmt::format("Found compatible systems: {}",
                                    compatibleSystemTypes)
                            .c_str());
                    // Use compatible systems information to find config file
                    findConfigFile(compatibleSystemTypes);
                }
            }
        }
    }
    catch (const std::exception&)
    {
        // Compatible system types information is not available.
    }
}

void UCD90320Monitor::findConfigFile(
    const std::vector<std::string>& compatibleSystemTypes)
{
    // Expected config file path name:
    // /usr/share/phosphor-power-sequencer/UCD90320Monitor_<systemType>.json

    // Add possible file names based on compatible system types (if any)
    for (const std::string& systemType : compatibleSystemTypes)
    {
        // Check if file exists
        std::filesystem::path pathName{
            "/usr/share/phosphor-power-sequencer/UCD90320Monitor_" +
            systemType + ".json"};
        if (std::filesystem::exists(pathName))
        {
            log<level::INFO>(
                fmt::format("Config file path: {}", pathName.string()).c_str());
            parseConfigFile(pathName);
            break;
        }
    }
}

void UCD90320Monitor::interfacesAddedHandler(sdbusplus::message::message& msg)
{
    // Only continue if message is valid and rails / pins have not already been
    // found
    if (!msg || !rails.empty())
    {
        return;
    }

    try
    {
        // Read the dbus message
        sdbusplus::message::object_path objPath;
        std::map<std::string,
                 std::map<std::string, std::variant<std::vector<std::string>>>>
            interfaces;
        msg.read(objPath, interfaces);

        // Find the compatible interface, if present
        auto itIntf = interfaces.find(compatibleInterface);
        if (itIntf != interfaces.cend())
        {
            // Find the Names property of the compatible interface, if present
            auto itProp = itIntf->second.find(compatibleNamesProperty);
            if (itProp != itIntf->second.cend())
            {
                // Get value of Names property
                const auto& propValue = std::get<0>(itProp->second);
                if (!propValue.empty())
                {
                    log<level::INFO>(
                        fmt::format(
                            "InterfacesAdded for compatible systems: {}",
                            propValue)
                            .c_str());

                    // Use compatible systems information to find config file
                    findConfigFile(propValue);
                }
            }
        }
    }
    catch (const std::exception&)
    {
        // Error trying to read interfacesAdded message.
    }
}

bool UCD90320Monitor::isPresent(const std::string& inventoryPath)
{
    // Empty path indicates no presence check is needed
    if (inventoryPath.empty())
    {
        return true;
    }

    // Get presence from D-Bus interface/property
    try
    {
        bool present{true};
        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, inventoryPath,
                          INVENTORY_MGR_IFACE, bus, present);
        log<level::INFO>(
            fmt::format("Presence, path: {}, value: {}", inventoryPath, present)
                .c_str());
        return present;
    }
    catch (const std::exception& e)
    {
        log<level::INFO>(
            fmt::format("Error getting presence property, path: {}, error: {}",
                        inventoryPath, e.what())
                .c_str());
        return false;
    }
}

void UCD90320Monitor::parseConfigFile(const std::filesystem::path& pathName)
{
    try
    {
        std::ifstream file{pathName};
        json rootElement = json::parse(file);

        // Parse rail information from config file
        auto railsIterator = rootElement.find("rails");
        if (railsIterator != rootElement.end())
        {
            for (const auto& railElement : *railsIterator)
            {
                auto nameIterator = railElement.find("name");

                if (nameIterator != railElement.end())
                {
                    Rail rail;
                    rail.name = (*nameIterator).get<std::string>();

                    // Presence element is optional
                    auto presenceIterator = railElement.find("presence");
                    if (presenceIterator != railElement.end())
                    {
                        rail.presence = (*presenceIterator).get<std::string>();
                    }

                    log<level::DEBUG>(
                        fmt::format("Adding rail, name: {}, presence: {}",
                                    rail.name, rail.presence)
                            .c_str());
                    rails.emplace_back(std::move(rail));
                }
                else
                {
                    log<level::ERR>(
                        fmt::format(
                            "No name found within rail in configuration file: {}",
                            pathName.string())
                            .c_str());
                }
            }
        }
        else
        {
            log<level::ERR>(
                fmt::format("No rails found in configuration file: {}",
                            pathName.string())
                    .c_str());
        }
        log<level::DEBUG>(
            fmt::format("Found number of rails: {}", rails.size()).c_str());

        // Parse pin information from config file
        auto pinsIterator = rootElement.find("pins");
        if (pinsIterator != rootElement.end())
        {
            for (const auto& pinElement : *pinsIterator)
            {
                auto nameIterator = pinElement.find("name");
                auto lineIterator = pinElement.find("line");

                if (nameIterator != pinElement.end() &&
                    lineIterator != pinElement.end())
                {
                    Pin pin;
                    pin.name = (*nameIterator).get<std::string>();
                    pin.line = (*lineIterator).get<unsigned int>();

                    // Presence element is optional
                    auto presenceIterator = pinElement.find("presence");
                    if (presenceIterator != pinElement.end())
                    {
                        pin.presence = (*presenceIterator).get<std::string>();
                    }

                    log<level::DEBUG>(
                        fmt::format(
                            "Adding pin, name: {}, line: {}, presence: {}",
                            pin.name, pin.line, pin.presence)
                            .c_str());
                    pins.emplace_back(std::move(pin));
                }
                else
                {
                    log<level::ERR>(
                        fmt::format(
                            "No name or line found within pin in configuration file: {}",
                            pathName.string())
                            .c_str());
                }
            }
        }
        else
        {
            log<level::ERR>(
                fmt::format("No pins found in configuration file: {}",
                            pathName.string())
                    .c_str());
        }
        log<level::DEBUG>(
            fmt::format("Found number of pins: {}", pins.size()).c_str());
    }
    catch (const std::exception& e)
    {
        log<level::ERR>(
            fmt::format("Error parsing configuration file, error: {}", e.what())
                .c_str());
    }
}

void UCD90320Monitor::onFailure(bool timeout,
                                const std::string& powerSupplyError)
{
    // Wait before reading device data. This is to allow the
    // power supplies and other hardware time to complete failure processing.
    std::this_thread::sleep_for(std::chrono::seconds(7));

    std::string message;
    std::map<std::string, std::string> additionalData{};

    try
    {
        onFailureCheckRails(message, additionalData, powerSupplyError);
        onFailureCheckPins(message, additionalData);
    }
    catch (const std::exception& e)
    {
        log<level::ERR>(
            fmt::format("Error when collecting metadata, error: {}", e.what())
                .c_str());
        additionalData.emplace("ERROR", e.what());
    }

    if (message.empty())
    {
        // Could not isolate, but we know something failed, so issue a timeout
        // or generic power good error
        message = timeout ? "xyz.openbmc_project.Power.Error.PowerOnTimeout"
                          : "xyz.openbmc_project.Power.Error.Shutdown";
    }
    logError(message, additionalData);
    if (!timeout)
    {
        createBmcDump();
    }
}

void UCD90320Monitor::onFailureCheckPins(
    std::string& message, std::map<std::string, std::string>& additionalData)
{
    // Setup a list of all the GPIOs on the chip
    gpiod::chip chip{"ucd90320", gpiod::chip::OPEN_BY_LABEL};
    log<level::INFO>(fmt::format("GPIO chip name: {}", chip.name()).c_str());
    log<level::INFO>(fmt::format("GPIO chip label: {}", chip.label()).c_str());
    unsigned int numberLines = chip.num_lines();
    log<level::INFO>(
        fmt::format("GPIO chip number of lines: {}", numberLines).c_str());

    // Workaround libgpiod bulk line maximum by getting values from individual
    // lines
    std::vector<int> values;
    try
    {
        for (unsigned int offset = 0; offset < numberLines; ++offset)
        {
            gpiod::line line = chip.get_line(offset);
            line.request({"phosphor-power-control",
                          gpiod::line_request::DIRECTION_INPUT, 0});
            values.push_back(line.get_value());
            line.release();
        }
    }
    catch (const std::exception& e)
    {
        log<level::ERR>(
            fmt::format("Error reading device GPIOs, error: {}", e.what())
                .c_str());
        additionalData.emplace("GPIO_ERROR", e.what());
    }

    // Add GPIO values to additional data, device has 84 GPIO pins so that value
    // is expected
    if (numberLines == 84 && values.size() >= 84)
    {
        log<level::INFO>(fmt::format("MAR01-24 GPIO values: {}",
                                     std::span{values}.subspan(0, 24))
                             .c_str());
        additionalData.emplace(
            "MAR01_24_GPIO_VALUES",
            fmt::format("{}", std::span{values}.subspan(0, 24)));
        log<level::INFO>(fmt::format("EN1-32 GPIO values: {}",
                                     std::span{values}.subspan(24, 32))
                             .c_str());
        additionalData.emplace(
            "EN1_32_GPIO_VALUES",
            fmt::format("{}", std::span{values}.subspan(24, 32)));
        log<level::INFO>(fmt::format("LGP01-16 GPIO values: {}",
                                     std::span{values}.subspan(56, 16))
                             .c_str());
        additionalData.emplace(
            "LGP01_16_GPIO_VALUES",
            fmt::format("{}", std::span{values}.subspan(56, 16)));
        log<level::INFO>(fmt::format("DMON1-8 GPIO values: {}",
                                     std::span{values}.subspan(72, 8))
                             .c_str());
        additionalData.emplace(
            "DMON1_8_GPIO_VALUES",
            fmt::format("{}", std::span{values}.subspan(72, 8)));
        log<level::INFO>(fmt::format("GPIO1-4 GPIO values: {}",
                                     std::span{values}.subspan(80, 4))
                             .c_str());
        additionalData.emplace(
            "GPIO1_4_GPIO_VALUES",
            fmt::format("{}", std::span{values}.subspan(80, 4)));
    }
    else
    {
        log<level::INFO>(fmt::format("GPIO values: {}", values).c_str());
        additionalData.emplace("GPIO_VALUES", fmt::format("{}", values));
    }

    // Only check GPIOs if no rail fail was found
    if (message.empty())
    {
        for (size_t pin = 0; pin < pins.size(); ++pin)
        {
            unsigned int line = pins[pin].line;
            if (line < values.size())
            {
                int value = values[line];

                if ((value == 0) && isPresent(pins[pin].presence))
                {
                    additionalData.emplace("INPUT_NUM",
                                           fmt::format("{}", line));
                    additionalData.emplace("INPUT_NAME", pins[pin].name);
                    message =
                        "xyz.openbmc_project.Power.Error.PowerSequencerPGOODFault";
                    return;
                }
            }
        }
    }
}

void UCD90320Monitor::onFailureCheckRails(
    std::string& message, std::map<std::string, std::string>& additionalData,
    const std::string& powerSupplyError)
{
    auto statusWord = readStatusWord();
    additionalData.emplace("STATUS_WORD", fmt::format("{:#06x}", statusWord));
    try
    {
        additionalData.emplace("MFR_STATUS",
                               fmt::format("{:#014x}", readMFRStatus()));
    }
    catch (const std::exception& e)
    {
        log<level::ERR>(
            fmt::format("Error when collecting MFR_STATUS, error: {}", e.what())
                .c_str());
        additionalData.emplace("ERROR", e.what());
    }

    // The status_word register has a summary bit to tell us if each page even
    // needs to be checked
    if (statusWord & status_word::VOUT_FAULT)
    {
        constexpr size_t numberPages = 32;
        for (size_t page = 0; page < numberPages; page++)
        {
            auto statusVout = pmbusInterface.insertPageNum(STATUS_VOUT, page);
            if (pmbusInterface.exists(statusVout, Type::Debug))
            {
                uint8_t vout = pmbusInterface.read(statusVout, Type::Debug);

                if (vout)
                {
                    // If any bits are on log them, though some are just
                    // warnings so they won't cause errors
                    log<level::INFO>(
                        fmt::format("{}, value: {:#04x}", statusVout, vout)
                            .c_str());

                    // Log errors if any non-warning bits on
                    if (vout & ~status_vout::WARNING_MASK)
                    {
                        additionalData.emplace(
                            fmt::format("STATUS{}_VOUT", page),
                            fmt::format("{:#04x}", vout));

                        // Base the callouts on the first present vout failure
                        // found
                        if (message.empty() && (page < rails.size()) &&
                            isPresent(rails[page].presence))
                        {
                            additionalData.emplace("RAIL_NAME",
                                                   rails[page].name);

                            // Use power supply error if set and 12v rail has
                            // failed, else use voltage error
                            message =
                                ((page == 0) && !powerSupplyError.empty())
                                    ? powerSupplyError
                                    : "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault";
                        }
                    }
                }
            }
        }
    }
    // If no vout failure found, but power supply error is set, use power supply
    // error
    if (message.empty())
    {
        message = powerSupplyError;
    }
}

uint16_t UCD90320Monitor::readStatusWord()
{
    return pmbusInterface.read(STATUS_WORD, Type::Debug);
}

uint64_t UCD90320Monitor::readMFRStatus()
{
    const std::string mfrStatus = "mfr_status";
    return pmbusInterface.read(mfrStatus, Type::HwmonDeviceDebug);
}

} // namespace phosphor::power::sequencer
