/*
// Copyright (c) 2019 Intel 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 "DeviceMgmt.hpp"
#include "PSUEvent.hpp"
#include "PSUSensor.hpp"
#include "Utils.hpp"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus/match.hpp>

#include <array>
#include <cmath>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <regex>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

static constexpr bool debug = false;

static const I2CDeviceTypeMap sensorTypes{
    {"ADC128D818", I2CDeviceType{"adc128d818", true}},
    {"ADM1266", I2CDeviceType{"adm1266", true}},
    {"ADM1272", I2CDeviceType{"adm1272", true}},
    {"ADM1275", I2CDeviceType{"adm1275", true}},
    {"ADM1278", I2CDeviceType{"adm1278", true}},
    {"ADM1293", I2CDeviceType{"adm1293", true}},
    {"ADS1015", I2CDeviceType{"ads1015", true}},
    {"ADS7830", I2CDeviceType{"ads7830", true}},
    {"AHE50DC_FAN", I2CDeviceType{"ahe50dc_fan", true}},
    {"BMR490", I2CDeviceType{"bmr490", true}},
    {"cffps", I2CDeviceType{"cffps", true}},
    {"cffps1", I2CDeviceType{"cffps", true}},
    {"cffps2", I2CDeviceType{"cffps", true}},
    {"cffps3", I2CDeviceType{"cffps", true}},
    {"DPS800", I2CDeviceType{"dps800", true}},
    {"INA219", I2CDeviceType{"ina219", true}},
    {"INA230", I2CDeviceType{"ina230", true}},
    {"INA238", I2CDeviceType{"ina238", true}},
    {"IPSPS1", I2CDeviceType{"ipsps1", true}},
    {"IR38060", I2CDeviceType{"ir38060", true}},
    {"IR38164", I2CDeviceType{"ir38164", true}},
    {"IR38263", I2CDeviceType{"ir38263", true}},
    {"ISL68137", I2CDeviceType{"isl68137", true}},
    {"ISL68220", I2CDeviceType{"isl68220", true}},
    {"ISL68223", I2CDeviceType{"isl68223", true}},
    {"ISL69225", I2CDeviceType{"isl69225", true}},
    {"ISL69243", I2CDeviceType{"isl69243", true}},
    {"ISL69260", I2CDeviceType{"isl69260", true}},
    {"LM25066", I2CDeviceType{"lm25066", true}},
    {"LTC2945", I2CDeviceType{"ltc2945", true}},
    {"MAX5970", I2CDeviceType{"max5970", true}},
    {"MAX11607", I2CDeviceType{"max11607", false}},
    {"MAX16601", I2CDeviceType{"max16601", true}},
    {"MAX20710", I2CDeviceType{"max20710", true}},
    {"MAX20730", I2CDeviceType{"max20730", true}},
    {"MAX20734", I2CDeviceType{"max20734", true}},
    {"MAX20796", I2CDeviceType{"max20796", true}},
    {"MAX34451", I2CDeviceType{"max34451", true}},
    {"MP2856", I2CDeviceType{"mp2856", true}},
    {"MP2857", I2CDeviceType{"mp2857", true}},
    {"MP2971", I2CDeviceType{"mp2971", true}},
    {"MP2973", I2CDeviceType{"mp2973", true}},
    {"MP2975", I2CDeviceType{"mp2975", true}},
    {"MP5023", I2CDeviceType{"mp5023", true}},
    {"MP5990", I2CDeviceType{"mp5990", true}},
    {"NCP4200", I2CDeviceType{"ncp4200", true}},
    {"PLI1209BC", I2CDeviceType{"pli1209bc", true}},
    {"pmbus", I2CDeviceType{"pmbus", true}},
    {"PXE1610", I2CDeviceType{"pxe1610", true}},
    {"RAA228000", I2CDeviceType{"raa228000", true}},
    {"RAA228228", I2CDeviceType{"raa228228", true}},
    {"RAA228620", I2CDeviceType{"raa228620", true}},
    {"RAA229001", I2CDeviceType{"raa229001", true}},
    {"RAA229004", I2CDeviceType{"raa229004", true}},
    {"RAA229126", I2CDeviceType{"raa229126", true}},
    {"TDA38640", I2CDeviceType{"tda38640", true}},
    {"TPS53679", I2CDeviceType{"tps53679", true}},
    {"TPS546D24", I2CDeviceType{"tps546d24", true}},
    {"XDPE11280", I2CDeviceType{"xdpe11280", true}},
    {"XDPE12284", I2CDeviceType{"xdpe12284", true}},
    {"XDPE152C4", I2CDeviceType{"xdpe152c4", true}},
};

enum class DevTypes
{
    Unknown = 0,
    HWMON,
    IIO
};

struct DevParams
{
    unsigned int matchIndex = 0;
    std::string matchRegEx;
    std::string nameRegEx;
};

namespace fs = std::filesystem;

static boost::container::flat_map<std::string, std::shared_ptr<PSUSensor>>
    sensors;
static boost::container::flat_map<std::string, std::unique_ptr<PSUCombineEvent>>
    combineEvents;
static boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
    pwmSensors;
static boost::container::flat_map<std::string, std::string> sensorTable;
static boost::container::flat_map<std::string, PSUProperty> labelMatch;
static boost::container::flat_map<std::string, std::string> pwmTable;
static EventPathList eventMatch;
static GroupEventPathList groupEventMatch;
static EventPathList limitEventMatch;

static std::vector<PSUProperty> psuProperties;
static boost::container::flat_map<size_t, bool> cpuPresence;
static boost::container::flat_map<DevTypes, DevParams> devParamMap;

// Function CheckEvent will check each attribute from eventMatch table in the
// sysfs. If the attributes exists in sysfs, then store the complete path
// of the attribute into eventPathList.
void checkEvent(const std::string& directory, const EventPathList& eventMatch,
                EventPathList& eventPathList)
{
    for (const auto& match : eventMatch)
    {
        const std::vector<std::string>& eventAttrs = match.second;
        const std::string& eventName = match.first;
        for (const auto& eventAttr : eventAttrs)
        {
            std::string eventPath = directory;
            eventPath += "/";
            eventPath += eventAttr;

            std::ifstream eventFile(eventPath);
            if (!eventFile.good())
            {
                continue;
            }

            eventPathList[eventName].push_back(eventPath);
        }
    }
}

// Check Group Events which contains more than one targets in each combine
// events.
void checkGroupEvent(const std::string& directory,
                     const GroupEventPathList& groupEventMatch,
                     GroupEventPathList& groupEventPathList)
{
    for (const auto& match : groupEventMatch)
    {
        const std::string& groupEventName = match.first;
        const EventPathList events = match.second;
        EventPathList pathList;
        for (const auto& match : events)
        {
            const std::string& eventName = match.first;
            const std::vector<std::string>& eventAttrs = match.second;
            for (const auto& eventAttr : eventAttrs)
            {
                std::string eventPath = directory;
                eventPath += "/";
                eventPath += eventAttr;
                std::ifstream eventFile(eventPath);
                if (!eventFile.good())
                {
                    continue;
                }

                pathList[eventName].push_back(eventPath);
            }
        }
        groupEventPathList[groupEventName] = pathList;
    }
}

// Function checkEventLimits will check all the psu related xxx_input attributes
// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
// xxx_min_alarm exist, then store the existing paths of the alarm attributes
// to eventPathList.
void checkEventLimits(const std::string& sensorPathStr,
                      const EventPathList& limitEventMatch,
                      EventPathList& eventPathList)
{
    auto attributePartPos = sensorPathStr.find_last_of('_');
    if (attributePartPos == std::string::npos)
    {
        // There is no '_' in the string, skip it
        return;
    }
    auto attributePart =
        std::string_view(sensorPathStr).substr(attributePartPos + 1);
    if (attributePart != "input")
    {
        // If the sensor is not xxx_input, skip it
        return;
    }

    auto prefixPart = sensorPathStr.substr(0, attributePartPos + 1);
    for (const auto& limitMatch : limitEventMatch)
    {
        const std::vector<std::string>& limitEventAttrs = limitMatch.second;
        const std::string& eventName = limitMatch.first;
        for (const auto& limitEventAttr : limitEventAttrs)
        {
            auto limitEventPath = prefixPart + limitEventAttr;
            std::ifstream eventFile(limitEventPath);
            if (!eventFile.good())
            {
                continue;
            }
            eventPathList[eventName].push_back(limitEventPath);
        }
    }
}

static void
    checkPWMSensor(const fs::path& sensorPath, std::string& labelHead,
                   const std::string& interfacePath,
                   std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
                   sdbusplus::asio::object_server& objectServer,
                   const std::string& psuName)
{
    for (const auto& [pwmLabel, pwmName] : pwmTable)
    {
        if (pwmLabel != labelHead)
        {
            continue;
        }

        const std::string& sensorPathStr = sensorPath.string();
        const std::string& pwmPathStr =
            boost::replace_all_copy(sensorPathStr, "input", "target");
        std::ifstream pwmFile(pwmPathStr);
        if (!pwmFile.good())
        {
            continue;
        }

        auto findPWMSensor = pwmSensors.find(psuName + labelHead);
        if (findPWMSensor != pwmSensors.end())
        {
            continue;
        }

        std::string name = "Pwm_";
        name += psuName;
        name += "_";
        name += pwmName;

        std::string objPath = interfacePath;
        objPath += "_";
        objPath += pwmName;

        pwmSensors[psuName + labelHead] = std::make_unique<PwmSensor>(
            name, pwmPathStr, dbusConnection, objectServer, objPath, "PSU");
    }
}

static void createSensorsCallback(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
    const ManagedObjectType& sensorConfigs,
    const std::shared_ptr<boost::container::flat_set<std::string>>&
        sensorsChanged,
    bool activateOnly)
{
    int numCreated = 0;
    bool firstScan = sensorsChanged == nullptr;

    auto devices = instantiateDevices(sensorConfigs, sensors, sensorTypes);

    std::vector<fs::path> pmbusPaths;
    findFiles(fs::path("/sys/bus/iio/devices"), "name", pmbusPaths);
    findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths);
    if (pmbusPaths.empty())
    {
        std::cerr << "No PSU sensors in system\n";
        return;
    }

    boost::container::flat_set<std::string> directories;
    for (const auto& pmbusPath : pmbusPaths)
    {
        EventPathList eventPathList;
        GroupEventPathList groupEventPathList;

        std::ifstream nameFile(pmbusPath);
        if (!nameFile.good())
        {
            std::cerr << "Failure finding pmbus path " << pmbusPath << "\n";
            continue;
        }

        std::string pmbusName;
        std::getline(nameFile, pmbusName);
        nameFile.close();

        if (sensorTypes.find(pmbusName) == sensorTypes.end())
        {
            // To avoid this error message, add your driver name to
            // the pmbusNames vector at the top of this file.
            std::cerr << "Driver name " << pmbusName
                      << " not found in sensor whitelist\n";
            continue;
        }

        auto directory = pmbusPath.parent_path();

        auto ret = directories.insert(directory.string());
        if (!ret.second)
        {
            std::cerr << "Duplicate path " << directory.string() << "\n";
            continue; // check if path has already been searched
        }

        DevTypes devType = DevTypes::HWMON;
        std::string deviceName;
        if (directory.parent_path() == "/sys/class/hwmon")
        {
            deviceName = fs::canonical(directory / "device").stem();
        }
        else
        {
            deviceName = fs::canonical(directory).parent_path().stem();
            devType = DevTypes::IIO;
        }

        size_t bus = 0;
        size_t addr = 0;
        if (!getDeviceBusAddr(deviceName, bus, addr))
        {
            continue;
        }

        const SensorBaseConfigMap* baseConfig = nullptr;
        const SensorData* sensorData = nullptr;
        const std::string* interfacePath = nullptr;
        std::string sensorType;
        size_t thresholdConfSize = 0;

        for (const auto& [path, cfgData] : sensorConfigs)
        {
            sensorData = &cfgData;
            for (const auto& [type, dt] : sensorTypes)
            {
                auto sensorBase = sensorData->find(configInterfaceName(type));
                if (sensorBase != sensorData->end())
                {
                    baseConfig = &sensorBase->second;
                    sensorType = type;
                    break;
                }
            }
            if (baseConfig == nullptr)
            {
                std::cerr << "error finding base configuration for "
                          << deviceName << "\n";
                continue;
            }

            auto configBus = baseConfig->find("Bus");
            auto configAddress = baseConfig->find("Address");

            if (configBus == baseConfig->end() ||
                configAddress == baseConfig->end())
            {
                std::cerr << "error finding necessary entry in configuration\n";
                continue;
            }

            const uint64_t* confBus =
                std::get_if<uint64_t>(&(configBus->second));
            const uint64_t* confAddr =
                std::get_if<uint64_t>(&(configAddress->second));
            if (confBus == nullptr || confAddr == nullptr)
            {
                std::cerr
                    << "Cannot get bus or address, invalid configuration\n";
                continue;
            }

            if ((*confBus != bus) || (*confAddr != addr))
            {
                if constexpr (debug)
                {
                    std::cerr << "Configuration skipping " << *confBus << "-"
                              << *confAddr << " because not " << bus << "-"
                              << addr << "\n";
                }
                continue;
            }

            std::vector<thresholds::Threshold> confThresholds;
            if (!parseThresholdsFromConfig(*sensorData, confThresholds))
            {
                std::cerr << "error populating total thresholds\n";
            }
            thresholdConfSize = confThresholds.size();

            interfacePath = &path.str;
            break;
        }
        if (interfacePath == nullptr)
        {
            // To avoid this error message, add your export map entry,
            // from Entity Manager, to sensorTypes at the top of this file.
            std::cerr << "failed to find match for " << deviceName << "\n";
            continue;
        }

        auto findI2CDev = devices.find(*interfacePath);

        std::shared_ptr<I2CDevice> i2cDev;
        if (findI2CDev != devices.end())
        {
            if (activateOnly && !findI2CDev->second.second)
            {
                continue;
            }
            i2cDev = findI2CDev->second.first;
        }

        auto findPSUName = baseConfig->find("Name");
        if (findPSUName == baseConfig->end())
        {
            std::cerr << "could not determine configuration name for "
                      << deviceName << "\n";
            continue;
        }
        const std::string* psuName =
            std::get_if<std::string>(&(findPSUName->second));
        if (psuName == nullptr)
        {
            std::cerr << "Cannot find psu name, invalid configuration\n";
            continue;
        }

        auto findCPU = baseConfig->find("CPURequired");
        if (findCPU != baseConfig->end())
        {
            size_t index = std::visit(VariantToIntVisitor(), findCPU->second);
            auto presenceFind = cpuPresence.find(index);
            if (presenceFind == cpuPresence.end() || !presenceFind->second)
            {
                continue;
            }
        }

        // on rescans, only update sensors we were signaled by
        if (!firstScan)
        {
            std::string psuNameStr = "/" + escapeName(*psuName);
            auto it = std::find_if(sensorsChanged->begin(),
                                   sensorsChanged->end(),
                                   [psuNameStr](std::string& s) {
                return s.ends_with(psuNameStr);
            });

            if (it == sensorsChanged->end())
            {
                continue;
            }
            sensorsChanged->erase(it);
        }
        checkEvent(directory.string(), eventMatch, eventPathList);
        checkGroupEvent(directory.string(), groupEventMatch,
                        groupEventPathList);

        PowerState readState = getPowerState(*baseConfig);

        /* Check if there are more sensors in the same interface */
        int i = 1;
        std::vector<std::string> psuNames;
        do
        {
            // Individual string fields: Name, Name1, Name2, Name3, ...
            psuNames.push_back(
                escapeName(std::get<std::string>(findPSUName->second)));
            findPSUName = baseConfig->find("Name" + std::to_string(i++));
        } while (findPSUName != baseConfig->end());

        std::vector<fs::path> sensorPaths;
        if (!findFiles(directory, devParamMap[devType].matchRegEx, sensorPaths,
                       0))
        {
            std::cerr << "No PSU non-label sensor in PSU\n";
            continue;
        }

        /* read max value in sysfs for in, curr, power, temp, ... */
        if (!findFiles(directory, R"(\w\d+_max$)", sensorPaths, 0))
        {
            if constexpr (debug)
            {
                std::cerr << "No max name in PSU \n";
            }
        }

        float pollRate = getPollRate(*baseConfig, PSUSensor::defaultSensorPoll);

        /* Find array of labels to be exposed if it is defined in config */
        std::vector<std::string> findLabels;
        auto findLabelObj = baseConfig->find("Labels");
        if (findLabelObj != baseConfig->end())
        {
            findLabels =
                std::get<std::vector<std::string>>(findLabelObj->second);
        }

        std::regex sensorNameRegEx(devParamMap[devType].nameRegEx);
        std::smatch matches;

        for (const auto& sensorPath : sensorPaths)
        {
            bool maxLabel = false;
            std::string labelHead;
            std::string sensorPathStr = sensorPath.string();
            std::string sensorNameStr = sensorPath.filename();
            std::string sensorNameSubStr;
            if (std::regex_search(sensorNameStr, matches, sensorNameRegEx))
            {
                // hwmon *_input filename without number:
                // in, curr, power, temp, ...
                // iio in_*_raw filename without number:
                // voltage, temp, pressure, ...
                sensorNameSubStr = matches[devParamMap[devType].matchIndex];
            }
            else
            {
                std::cerr << "Could not extract the alpha prefix from "
                          << sensorNameStr;
                continue;
            }

            std::string labelPath;

            if (devType == DevTypes::HWMON)
            {
                /* find and differentiate _max and _input to replace "label" */
                size_t pos = sensorPathStr.find('_');
                if (pos != std::string::npos)
                {
                    std::string sensorPathStrMax = sensorPathStr.substr(pos);
                    if (sensorPathStrMax == "_max")
                    {
                        labelPath = boost::replace_all_copy(sensorPathStr,
                                                            "max", "label");
                        maxLabel = true;
                    }
                    else
                    {
                        labelPath = boost::replace_all_copy(sensorPathStr,
                                                            "input", "label");
                        maxLabel = false;
                    }
                }
                else
                {
                    continue;
                }

                std::ifstream labelFile(labelPath);
                if (!labelFile.good())
                {
                    if constexpr (debug)
                    {
                        std::cerr << "Input file " << sensorPath
                                  << " has no corresponding label file\n";
                    }
                    // hwmon *_input filename with number:
                    // temp1, temp2, temp3, ...
                    labelHead = sensorNameStr.substr(0,
                                                     sensorNameStr.find('_'));
                }
                else
                {
                    std::string label;
                    std::getline(labelFile, label);
                    labelFile.close();
                    auto findSensor = sensors.find(label);
                    if (findSensor != sensors.end())
                    {
                        continue;
                    }

                    // hwmon corresponding *_label file contents:
                    // vin1, vout1, ...
                    labelHead = label.substr(0, label.find(' '));
                }

                /* append "max" for labelMatch */
                if (maxLabel)
                {
                    labelHead.insert(0, "max");
                }

                checkPWMSensor(sensorPath, labelHead, *interfacePath,
                               dbusConnection, objectServer, psuNames[0]);
            }
            else if (devType == DevTypes::IIO)
            {
                auto findIIOHyphen = sensorNameStr.find_last_of('_');
                labelHead = sensorNameStr.substr(0, findIIOHyphen);
            }

            if constexpr (debug)
            {
                std::cerr << "Sensor type=\"" << sensorNameSubStr
                          << "\" label=\"" << labelHead << "\"\n";
            }

            if (!findLabels.empty())
            {
                /* Check if this labelHead is enabled in config file */
                if (std::find(findLabels.begin(), findLabels.end(),
                              labelHead) == findLabels.end())
                {
                    if constexpr (debug)
                    {
                        std::cerr << "could not find " << labelHead
                                  << " in the Labels list\n";
                    }
                    continue;
                }
            }

            auto findProperty = labelMatch.find(labelHead);
            if (findProperty == labelMatch.end())
            {
                if constexpr (debug)
                {
                    std::cerr << "Could not find matching default property for "
                              << labelHead << "\n";
                }
                continue;
            }

            // Protect the hardcoded labelMatch list from changes,
            // by making a copy and modifying that instead.
            // Avoid bleedthrough of one device's customizations to
            // the next device, as each should be independently customizable.
            psuProperties.push_back(findProperty->second);
            auto psuProperty = psuProperties.rbegin();

            // Use label head as prefix for reading from config file,
            // example if temp1: temp1_Name, temp1_Scale, temp1_Min, ...
            std::string keyName = labelHead + "_Name";
            std::string keyScale = labelHead + "_Scale";
            std::string keyMin = labelHead + "_Min";
            std::string keyMax = labelHead + "_Max";
            std::string keyOffset = labelHead + "_Offset";
            std::string keyPowerState = labelHead + "_PowerState";

            bool customizedName = false;
            auto findCustomName = baseConfig->find(keyName);
            if (findCustomName != baseConfig->end())
            {
                try
                {
                    psuProperty->labelTypeName = std::visit(
                        VariantToStringVisitor(), findCustomName->second);
                }
                catch (const std::invalid_argument&)
                {
                    std::cerr << "Unable to parse " << keyName << "\n";
                    continue;
                }

                // All strings are valid, including empty string
                customizedName = true;
            }

            bool customizedScale = false;
            auto findCustomScale = baseConfig->find(keyScale);
            if (findCustomScale != baseConfig->end())
            {
                try
                {
                    psuProperty->sensorScaleFactor = std::visit(
                        VariantToUnsignedIntVisitor(), findCustomScale->second);
                }
                catch (const std::invalid_argument&)
                {
                    std::cerr << "Unable to parse " << keyScale << "\n";
                    continue;
                }

                // Avoid later division by zero
                if (psuProperty->sensorScaleFactor > 0)
                {
                    customizedScale = true;
                }
                else
                {
                    std::cerr << "Unable to accept " << keyScale << "\n";
                    continue;
                }
            }

            auto findCustomMin = baseConfig->find(keyMin);
            if (findCustomMin != baseConfig->end())
            {
                try
                {
                    psuProperty->minReading = std::visit(
                        VariantToDoubleVisitor(), findCustomMin->second);
                }
                catch (const std::invalid_argument&)
                {
                    std::cerr << "Unable to parse " << keyMin << "\n";
                    continue;
                }
            }

            auto findCustomMax = baseConfig->find(keyMax);
            if (findCustomMax != baseConfig->end())
            {
                try
                {
                    psuProperty->maxReading = std::visit(
                        VariantToDoubleVisitor(), findCustomMax->second);
                }
                catch (const std::invalid_argument&)
                {
                    std::cerr << "Unable to parse " << keyMax << "\n";
                    continue;
                }
            }

            auto findCustomOffset = baseConfig->find(keyOffset);
            if (findCustomOffset != baseConfig->end())
            {
                try
                {
                    psuProperty->sensorOffset = std::visit(
                        VariantToDoubleVisitor(), findCustomOffset->second);
                }
                catch (const std::invalid_argument&)
                {
                    std::cerr << "Unable to parse " << keyOffset << "\n";
                    continue;
                }
            }

            // if we find label head power state set ，override the powerstate.
            auto findPowerState = baseConfig->find(keyPowerState);
            if (findPowerState != baseConfig->end())
            {
                std::string powerState = std::visit(VariantToStringVisitor(),
                                                    findPowerState->second);
                setReadState(powerState, readState);
            }
            if (!(psuProperty->minReading < psuProperty->maxReading))
            {
                std::cerr << "Min must be less than Max\n";
                continue;
            }

            // If the sensor name is being customized by config file,
            // then prefix/suffix composition becomes not necessary,
            // and in fact not wanted, because it gets in the way.
            std::string psuNameFromIndex;
            if (!customizedName)
            {
                /* Find out sensor name index for this label */
                std::regex rgx("[A-Za-z]+([0-9]+)");
                size_t nameIndex{0};
                if (std::regex_search(labelHead, matches, rgx))
                {
                    nameIndex = std::stoi(matches[1]);

                    // Decrement to preserve alignment, because hwmon
                    // human-readable filenames and labels use 1-based
                    // numbering, but the "Name", "Name1", "Name2", etc. naming
                    // convention (the psuNames vector) uses 0-based numbering.
                    if (nameIndex > 0)
                    {
                        --nameIndex;
                    }
                }
                else
                {
                    nameIndex = 0;
                }

                if (psuNames.size() <= nameIndex)
                {
                    std::cerr << "Could not pair " << labelHead
                              << " with a Name field\n";
                    continue;
                }

                psuNameFromIndex = psuNames[nameIndex];

                if constexpr (debug)
                {
                    std::cerr << "Sensor label head " << labelHead
                              << " paired with " << psuNameFromIndex
                              << " at index " << nameIndex << "\n";
                }
            }

            if (devType == DevTypes::HWMON)
            {
                checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
            }

            // Similarly, if sensor scaling factor is being customized,
            // then the below power-of-10 constraint becomes unnecessary,
            // as config should be able to specify an arbitrary divisor.
            unsigned int factor = psuProperty->sensorScaleFactor;
            if (!customizedScale)
            {
                // Preserve existing usage of hardcoded labelMatch table below
                factor = std::pow(10.0, factor);

                /* Change first char of substring to uppercase */
                char firstChar =
                    static_cast<char>(std::toupper(sensorNameSubStr[0]));
                std::string strScaleFactor =
                    firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";

                // Preserve existing configs by accepting earlier syntax,
                // example CurrScaleFactor, PowerScaleFactor, ...
                auto findScaleFactor = baseConfig->find(strScaleFactor);
                if (findScaleFactor != baseConfig->end())
                {
                    factor = std::visit(VariantToIntVisitor(),
                                        findScaleFactor->second);
                }

                if constexpr (debug)
                {
                    std::cerr << "Sensor scaling factor " << factor
                              << " string " << strScaleFactor << "\n";
                }
            }

            std::vector<thresholds::Threshold> sensorThresholds;
            if (!parseThresholdsFromConfig(*sensorData, sensorThresholds,
                                           &labelHead))
            {
                std::cerr << "error populating thresholds for "
                          << sensorNameSubStr << "\n";
            }

            auto findSensorUnit = sensorTable.find(sensorNameSubStr);
            if (findSensorUnit == sensorTable.end())
            {
                std::cerr << sensorNameSubStr
                          << " is not a recognized sensor type\n";
                continue;
            }

            if constexpr (debug)
            {
                std::cerr << "Sensor properties: Name \""
                          << psuProperty->labelTypeName << "\" Scale "
                          << psuProperty->sensorScaleFactor << " Min "
                          << psuProperty->minReading << " Max "
                          << psuProperty->maxReading << " Offset "
                          << psuProperty->sensorOffset << "\n";
            }

            std::string sensorName = psuProperty->labelTypeName;
            if (customizedName)
            {
                if (sensorName.empty())
                {
                    // Allow selective disabling of an individual sensor,
                    // by customizing its name to an empty string.
                    std::cerr << "Sensor disabled, empty string\n";
                    continue;
                }
            }
            else
            {
                // Sensor name not customized, do prefix/suffix composition,
                // preserving default behavior by using psuNameFromIndex.
                sensorName = psuNameFromIndex + " " +
                             psuProperty->labelTypeName;
            }

            if constexpr (debug)
            {
                std::cerr << "Sensor name \"" << sensorName << "\" path \""
                          << sensorPathStr << "\" type \"" << sensorType
                          << "\"\n";
            }
            // destruct existing one first if already created

            auto& sensor = sensors[sensorName];
            if (!activateOnly)
            {
                sensor = nullptr;
            }

            if (sensor != nullptr)
            {
                sensor->activate(sensorPathStr, i2cDev);
            }
            else
            {
                sensors[sensorName] = std::make_shared<PSUSensor>(
                    sensorPathStr, sensorType, objectServer, dbusConnection, io,
                    sensorName, std::move(sensorThresholds), *interfacePath,
                    readState, findSensorUnit->second, factor,
                    psuProperty->maxReading, psuProperty->minReading,
                    psuProperty->sensorOffset, labelHead, thresholdConfSize,
                    pollRate, i2cDev);
                sensors[sensorName]->setupRead();
                ++numCreated;
                if constexpr (debug)
                {
                    std::cerr << "Created " << numCreated
                              << " sensors so far\n";
                }
            }
        }

        if (devType == DevTypes::HWMON)
        {
            // OperationalStatus event
            combineEvents[*psuName + "OperationalStatus"] = nullptr;
            combineEvents[*psuName + "OperationalStatus"] =
                std::make_unique<PSUCombineEvent>(
                    objectServer, dbusConnection, io, *psuName, readState,
                    eventPathList, groupEventPathList, "OperationalStatus",
                    pollRate);
        }
    }

    if constexpr (debug)
    {
        std::cerr << "Created total of " << numCreated << " sensors\n";
    }
}

static void
    getPresentCpus(std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
{
    static const int depth = 2;
    static const int numKeys = 1;
    GetSubTreeType cpuSubTree;

    try
    {
        auto getItems = dbusConnection->new_method_call(
            mapper::busName, mapper::path, mapper::interface, mapper::subtree);
        getItems.append(cpuInventoryPath, static_cast<int32_t>(depth),
                        std::array<const char*, numKeys>{
                            "xyz.openbmc_project.Inventory.Item"});
        auto getItemsResp = dbusConnection->call(getItems);
        getItemsResp.read(cpuSubTree);
    }
    catch (sdbusplus::exception_t& e)
    {
        std::cerr << "error getting inventory item subtree: " << e.what()
                  << "\n";
        return;
    }

    for (const auto& [path, objDict] : cpuSubTree)
    {
        auto obj = sdbusplus::message::object_path(path).filename();
        if (!obj.starts_with("cpu") || objDict.empty())
        {
            continue;
        }
        const std::string& owner = objDict.begin()->first;

        std::variant<bool> respValue;
        try
        {
            auto getPresence = dbusConnection->new_method_call(
                owner.c_str(), path.c_str(), "org.freedesktop.DBus.Properties",
                "Get");
            getPresence.append("xyz.openbmc_project.Inventory.Item", "Present");
            auto resp = dbusConnection->call(getPresence);
            resp.read(respValue);
        }
        catch (sdbusplus::exception_t& e)
        {
            std::cerr << "Error in getting CPU presence: " << e.what() << "\n";
            continue;
        }

        auto* present = std::get_if<bool>(&respValue);
        if (present != nullptr && *present)
        {
            int cpuIndex = 0;
            try
            {
                cpuIndex = std::stoi(obj.substr(obj.find_last_of("cpu") + 1));
            }
            catch (const std::exception& e)
            {
                std::cerr << "Error converting CPU index, " << e.what() << '\n';
                continue;
            }
            cpuPresence[cpuIndex + 1] = *present;
        }
    }
}

void createSensors(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
    const std::shared_ptr<boost::container::flat_set<std::string>>&
        sensorsChanged,
    bool activateOnly)
{
    auto getter = std::make_shared<GetSensorConfiguration>(
        dbusConnection, [&io, &objectServer, &dbusConnection, sensorsChanged,
                         activateOnly](const ManagedObjectType& sensorConfigs) {
        createSensorsCallback(io, objectServer, dbusConnection, sensorConfigs,
                              sensorsChanged, activateOnly);
    });
    std::vector<std::string> types(sensorTypes.size());
    for (const auto& [type, dt] : sensorTypes)
    {
        types.push_back(type);
    }
    getter->getConfiguration(types);
}

void propertyInitialize(void)
{
    sensorTable = {{"power", sensor_paths::unitWatts},
                   {"curr", sensor_paths::unitAmperes},
                   {"temp", sensor_paths::unitDegreesC},
                   {"in", sensor_paths::unitVolts},
                   {"voltage", sensor_paths::unitVolts},
                   {"fan", sensor_paths::unitRPMs}};

    labelMatch = {
        {"pin", PSUProperty("Input Power", 3000, 0, 6, 0)},
        {"pin1", PSUProperty("Input Power", 3000, 0, 6, 0)},
        {"pin2", PSUProperty("Input Power", 3000, 0, 6, 0)},
        {"pout1", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"pout2", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"pout3", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"power1", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"power2", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"power3", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"power4", PSUProperty("Output Power", 3000, 0, 6, 0)},
        {"maxpin", PSUProperty("Max Input Power", 3000, 0, 6, 0)},
        {"vin", PSUProperty("Input Voltage", 300, 0, 3, 0)},
        {"vin1", PSUProperty("Input Voltage", 300, 0, 3, 0)},
        {"vin2", PSUProperty("Input Voltage", 300, 0, 3, 0)},
        {"maxvin", PSUProperty("Max Input Voltage", 300, 0, 3, 0)},
        {"in_voltage0", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in_voltage1", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in_voltage2", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in_voltage3", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout1", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout2", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout3", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout4", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout5", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout6", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout7", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout8", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout9", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout10", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout11", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout12", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout13", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout14", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout15", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout16", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout17", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout18", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout19", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout20", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout21", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout22", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout23", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout24", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout25", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout26", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout27", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout28", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout29", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout30", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout31", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vout32", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"vmon", PSUProperty("Auxiliary Input Voltage", 255, 0, 3, 0)},
        {"in0", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in1", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in2", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in3", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in4", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in5", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in6", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"in7", PSUProperty("Output Voltage", 255, 0, 3, 0)},
        {"iin", PSUProperty("Input Current", 20, 0, 3, 0)},
        {"iin1", PSUProperty("Input Current", 20, 0, 3, 0)},
        {"iin2", PSUProperty("Input Current", 20, 0, 3, 0)},
        {"iout1", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout2", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout3", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout4", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout5", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout6", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout7", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout8", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout9", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout10", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout11", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout12", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout13", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"iout14", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"curr1", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"curr2", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"curr3", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"curr4", PSUProperty("Output Current", 255, 0, 3, 0)},
        {"maxiout1", PSUProperty("Max Output Current", 255, 0, 3, 0)},
        {"temp1", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"temp2", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"temp3", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"temp4", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"temp5", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"temp6", PSUProperty("Temperature", 127, -128, 3, 0)},
        {"maxtemp1", PSUProperty("Max Temperature", 127, -128, 3, 0)},
        {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0, 0)},
        {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0, 0)},
        {"fan3", PSUProperty("Fan Speed 3", 30000, 0, 0, 0)},
        {"fan4", PSUProperty("Fan Speed 4", 30000, 0, 0, 0)}};

    pwmTable = {{"fan1", "Fan_1"},
                {"fan2", "Fan_2"},
                {"fan3", "Fan_3"},
                {"fan4", "Fan_4"}};

    limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
                       {"Failure", {"crit_alarm", "lcrit_alarm"}}};

    eventMatch = {{"PredictiveFailure", {"power1_alarm"}},
                  {"Failure", {"in2_alarm"}},
                  {"ACLost", {"in1_beep"}},
                  {"ConfigureError", {"in1_fault"}}};

    groupEventMatch = {{"FanFault",
                        {{"fan1", {"fan1_alarm", "fan1_fault"}},
                         {"fan2", {"fan2_alarm", "fan2_fault"}},
                         {"fan3", {"fan3_alarm", "fan3_fault"}},
                         {"fan4", {"fan4_alarm", "fan4_fault"}}}}};

    devParamMap = {
        {DevTypes::HWMON, {1, R"(\w\d+_input$)", "([A-Za-z]+)[0-9]*_"}},
        {DevTypes::IIO,
         {2, R"(\w+_(raw|input)$)", "^(in|out)_([A-Za-z]+)[0-9]*_"}}};
}

static void powerStateChanged(
    PowerState type, bool newState,
    boost::container::flat_map<std::string, std::shared_ptr<PSUSensor>>&
        sensors,
    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
{
    if (newState)
    {
        createSensors(io, objectServer, dbusConnection, nullptr, true);
    }
    else
    {
        for (auto& [path, sensor] : sensors)
        {
            if (sensor != nullptr && sensor->readState == type)
            {
                sensor->deactivate();
            }
        }
    }
}

int main()
{
    boost::asio::io_context io;
    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);

    sdbusplus::asio::object_server objectServer(systemBus, true);
    objectServer.add_manager("/xyz/openbmc_project/sensors");
    objectServer.add_manager("/xyz/openbmc_project/control");
    systemBus->request_name("xyz.openbmc_project.PSUSensor");
    auto sensorsChanged =
        std::make_shared<boost::container::flat_set<std::string>>();

    propertyInitialize();

    auto powerCallBack = [&io, &objectServer, &systemBus](PowerState type,
                                                          bool state) {
        powerStateChanged(type, state, sensors, io, objectServer, systemBus);
    };

    setupPowerMatchCallback(systemBus, powerCallBack);

    boost::asio::post(io, [&]() {
        createSensors(io, objectServer, systemBus, nullptr, false);
    });
    boost::asio::steady_timer filterTimer(io);
    std::function<void(sdbusplus::message_t&)> eventHandler =
        [&](sdbusplus::message_t& message) {
        if (message.is_method_error())
        {
            std::cerr << "callback method error\n";
            return;
        }
        sensorsChanged->insert(message.get_path());
        filterTimer.expires_after(std::chrono::seconds(3));
        filterTimer.async_wait([&](const boost::system::error_code& ec) {
            if (ec == boost::asio::error::operation_aborted)
            {
                return;
            }
            if (ec)
            {
                std::cerr << "timer error\n";
            }
            createSensors(io, objectServer, systemBus, sensorsChanged, false);
        });
    };

    boost::asio::steady_timer cpuFilterTimer(io);
    std::function<void(sdbusplus::message_t&)> cpuPresenceHandler =
        [&](sdbusplus::message_t& message) {
        std::string path = message.get_path();
        boost::to_lower(path);

        sdbusplus::message::object_path cpuPath(path);
        std::string cpuName = cpuPath.filename();
        if (!cpuName.starts_with("cpu"))
        {
            return;
        }
        size_t index = 0;
        try
        {
            index = std::stoi(path.substr(path.size() - 1));
        }
        catch (const std::invalid_argument&)
        {
            std::cerr << "Found invalid path " << path << "\n";
            return;
        }

        std::string objectName;
        boost::container::flat_map<std::string, std::variant<bool>> values;
        message.read(objectName, values);
        auto findPresence = values.find("Present");
        try
        {
            cpuPresence[index] = std::get<bool>(findPresence->second);
        }
        catch (const std::bad_variant_access& err)
        {
            return;
        }

        if (!cpuPresence[index])
        {
            return;
        }
        cpuFilterTimer.expires_after(std::chrono::seconds(1));
        cpuFilterTimer.async_wait([&](const boost::system::error_code& ec) {
            if (ec == boost::asio::error::operation_aborted)
            {
                return;
            }
            if (ec)
            {
                std::cerr << "timer error\n";
                return;
            }
            createSensors(io, objectServer, systemBus, nullptr, false);
        });
    };

    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);

    matches.emplace_back(std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*systemBus),
        "type='signal',member='PropertiesChanged',path_namespace='" +
            std::string(cpuInventoryPath) +
            "',arg0namespace='xyz.openbmc_project.Inventory.Item'",
        cpuPresenceHandler));

    getPresentCpus(systemBus);

    setupManufacturingModeMatch(*systemBus);
    io.run();
}
