/*
// Copyright (c) 2017 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 "PwmSensor.hpp"
#include "TachSensor.hpp"
#include "Utils.hpp"
#include "VariantVisitors.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 <filesystem>
#include <fstream>
#include <functional>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <utility>
#include <variant>
#include <vector>

namespace fs = std::filesystem;

// The following two structures need to be consistent
static auto sensorTypes{std::to_array<const char*>(
    {"AspeedFan", "I2CFan", "NuvotonFan", "HPEFan"})};

enum FanTypes
{
    aspeed = 0,
    i2c,
    nuvoton,
    hpe,
    max,
};

static_assert(std::tuple_size<decltype(sensorTypes)>::value == FanTypes::max,
              "sensorTypes element number is not equal to FanTypes number");

constexpr const char* redundancyConfiguration =
    "xyz.openbmc_project.Configuration.FanRedundancy";
static std::regex inputRegex(R"(fan(\d+)_input)");

// todo: power supply fan redundancy
std::optional<RedundancySensor> systemRedundancy;

static const std::map<std::string, FanTypes> compatibleFanTypes = {
    {"aspeed,ast2400-pwm-tacho", FanTypes::aspeed},
    {"aspeed,ast2500-pwm-tacho", FanTypes::aspeed},
    {"nuvoton,npcm750-pwm-fan", FanTypes::nuvoton},
    {"hpe,gxp-fan-ctrl", FanTypes::hpe}
    // add compatible string here for new fan type
};

FanTypes getFanType(const fs::path& parentPath)
{
    fs::path linkPath = parentPath / "of_node";
    if (!fs::exists(linkPath))
    {
        return FanTypes::i2c;
    }

    std::string canonical = fs::canonical(linkPath);
    std::string compatiblePath = canonical + "/compatible";
    std::ifstream compatibleStream(compatiblePath);

    if (!compatibleStream)
    {
        std::cerr << "Error opening " << compatiblePath << "\n";
        return FanTypes::i2c;
    }

    std::string compatibleString;
    while (std::getline(compatibleStream, compatibleString))
    {
        compatibleString.pop_back(); // trim EOL before comparisons

        std::map<std::string, FanTypes>::const_iterator compatibleIterator =
            compatibleFanTypes.find(compatibleString);

        if (compatibleIterator != compatibleFanTypes.end())
        {
            return compatibleIterator->second;
        }
    }

    return FanTypes::i2c;
}
void enablePwm(const fs::path& filePath)
{
    std::fstream enableFile(filePath, std::ios::in | std::ios::out);
    if (!enableFile.good())
    {
        std::cerr << "Error read/write " << filePath << "\n";
        return;
    }

    std::string regulateMode;
    std::getline(enableFile, regulateMode);
    if (regulateMode == "0")
    {
        enableFile << 1;
    }
}
bool findPwmfanPath(unsigned int configPwmfanIndex, fs::path& pwmPath)
{
    /* Search PWM since pwm-fan had separated
     * PWM from tach directory and 1 channel only*/
    std::vector<fs::path> pwmfanPaths;
    std::string pwnfanDevName("pwm-fan");

    pwnfanDevName += std::to_string(configPwmfanIndex);

    if (!findFiles(fs::path("/sys/class/hwmon"), R"(pwm\d+)", pwmfanPaths))
    {
        std::cerr << "No PWMs are found!\n";
        return false;
    }
    for (const auto& path : pwmfanPaths)
    {
        std::error_code ec;
        fs::path link = fs::read_symlink(path.parent_path() / "device", ec);

        if (ec)
        {
            std::cerr << "read_symlink() failed: " << ec.message() << " ("
                      << ec.value() << ")\n";
            continue;
        }

        if (link.filename().string() == pwnfanDevName)
        {
            pwmPath = path;
            return true;
        }
    }
    return false;
}
bool findPwmPath(const fs::path& directory, unsigned int pwm, fs::path& pwmPath)
{
    std::error_code ec;

    /* Assuming PWM file is appeared in the same directory as fanX_input */
    auto path = directory / ("pwm" + std::to_string(pwm + 1));
    bool exists = fs::exists(path, ec);

    if (ec || !exists)
    {
        /* PWM file not exist or error happened */
        if (ec)
        {
            std::cerr << "exists() failed: " << ec.message() << " ("
                      << ec.value() << ")\n";
        }
        /* try search form pwm-fanX directory */
        return findPwmfanPath(pwm, pwmPath);
    }

    pwmPath = path;
    return true;
}

// The argument to this function should be the fanN_input file that we want to
// enable. The function will locate the corresponding fanN_enable file if it
// exists. Note that some drivers don't provide this file if the sensors are
// always enabled.
void enableFanInput(const fs::path& fanInputPath)
{
    std::error_code ec;
    std::string path(fanInputPath.string());
    boost::replace_last(path, "input", "enable");

    bool exists = fs::exists(path, ec);
    if (ec || !exists)
    {
        return;
    }

    std::fstream enableFile(path, std::ios::out);
    if (!enableFile.good())
    {
        return;
    }
    enableFile << 1;
}

void createRedundancySensor(
    const boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>&
        sensors,
    const std::shared_ptr<sdbusplus::asio::connection>& conn,
    sdbusplus::asio::object_server& objectServer)
{

    conn->async_method_call(
        [&objectServer, &sensors](boost::system::error_code& ec,
                                  const ManagedObjectType& managedObj) {
        if (ec)
        {
            std::cerr << "Error calling entity manager \n";
            return;
        }
        for (const auto& [path, interfaces] : managedObj)
        {
            for (const auto& [intf, cfg] : interfaces)
            {
                if (intf == redundancyConfiguration)
                {
                    // currently only support one
                    auto findCount = cfg.find("AllowedFailures");
                    if (findCount == cfg.end())
                    {
                        std::cerr << "Malformed redundancy record \n";
                        return;
                    }
                    std::vector<std::string> sensorList;

                    for (const auto& [name, sensor] : sensors)
                    {
                        sensorList.push_back(
                            "/xyz/openbmc_project/sensors/fan_tach/" +
                            sensor->name);
                    }
                    systemRedundancy.reset();
                    systemRedundancy.emplace(
                        RedundancySensor(std::get<uint64_t>(findCount->second),
                                         sensorList, objectServer, path));

                    return;
                }
            }
        }
        },
        "xyz.openbmc_project.EntityManager", "/xyz/openbmc_project/inventory",
        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}

void createSensors(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
    boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>&
        tachSensors,
    boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>&
        pwmSensors,
    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
    const std::shared_ptr<boost::container::flat_set<std::string>>&
        sensorsChanged,
    size_t retries = 0)
{
    auto getter = std::make_shared<GetSensorConfiguration>(
        dbusConnection,
        [&io, &objectServer, &tachSensors, &pwmSensors, &dbusConnection,
         sensorsChanged](const ManagedObjectType& sensorConfigurations) {
        bool firstScan = sensorsChanged == nullptr;
        std::vector<fs::path> paths;
        if (!findFiles(fs::path("/sys/class/hwmon"), R"(fan\d+_input)", paths))
        {
            std::cerr << "No fan sensors in system\n";
            return;
        }

        // iterate through all found fan sensors, and try to match them with
        // configuration
        for (const auto& path : paths)
        {
            std::smatch match;
            std::string pathStr = path.string();

            std::regex_search(pathStr, match, inputRegex);
            std::string indexStr = *(match.begin() + 1);

            fs::path directory = path.parent_path();
            FanTypes fanType = getFanType(directory);
            std::string cfgIntf = configInterfaceName(sensorTypes[fanType]);

            // convert to 0 based
            size_t index = std::stoul(indexStr) - 1;

            const char* baseType = nullptr;
            const SensorData* sensorData = nullptr;
            const std::string* interfacePath = nullptr;
            const SensorBaseConfiguration* baseConfiguration = nullptr;
            for (const auto& [path, cfgData] : sensorConfigurations)
            {
                // find the base of the configuration to see if indexes
                // match
                auto sensorBaseFind = cfgData.find(cfgIntf);
                if (sensorBaseFind == cfgData.end())
                {
                    continue;
                }

                baseConfiguration = &(*sensorBaseFind);
                interfacePath = &path.str;
                baseType = sensorTypes[fanType];

                auto findIndex = baseConfiguration->second.find("Index");
                if (findIndex == baseConfiguration->second.end())
                {
                    std::cerr << baseConfiguration->first << " missing index\n";
                    continue;
                }
                unsigned int configIndex = std::visit(
                    VariantToUnsignedIntVisitor(), findIndex->second);
                if (configIndex != index)
                {
                    continue;
                }
                if (fanType == FanTypes::aspeed ||
                    fanType == FanTypes::nuvoton || fanType == FanTypes::hpe)
                {
                    // there will be only 1 aspeed or nuvoton or hpe sensor
                    // object in sysfs, we found the fan
                    sensorData = &cfgData;
                    break;
                }
                if (fanType == FanTypes::i2c)
                {
                    size_t bus = 0;
                    size_t address = 0;

                    std::string link =
                        fs::read_symlink(directory / "device").filename();

                    size_t findDash = link.find('-');
                    if (findDash == std::string::npos ||
                        link.size() <= findDash + 1)
                    {
                        std::cerr << "Error finding device from symlink";
                    }
                    bus = std::stoi(link.substr(0, findDash));
                    address = std::stoi(link.substr(findDash + 1), nullptr, 16);

                    auto findBus = baseConfiguration->second.find("Bus");
                    auto findAddress =
                        baseConfiguration->second.find("Address");
                    if (findBus == baseConfiguration->second.end() ||
                        findAddress == baseConfiguration->second.end())
                    {
                        std::cerr << baseConfiguration->first
                                  << " missing bus or address\n";
                        continue;
                    }
                    unsigned int configBus = std::visit(
                        VariantToUnsignedIntVisitor(), findBus->second);
                    unsigned int configAddress = std::visit(
                        VariantToUnsignedIntVisitor(), findAddress->second);

                    if (configBus == bus && configAddress == address)
                    {
                        sensorData = &cfgData;
                        break;
                    }
                }
            }
            if (sensorData == nullptr)
            {
                std::cerr << "failed to find match for " << path.string()
                          << "\n";
                continue;
            }

            auto findSensorName = baseConfiguration->second.find("Name");

            if (findSensorName == baseConfiguration->second.end())
            {
                std::cerr << "could not determine configuration name for "
                          << path.string() << "\n";
                continue;
            }
            std::string sensorName =
                std::get<std::string>(findSensorName->second);

            // on rescans, only update sensors we were signaled by
            auto findSensor = tachSensors.find(sensorName);
            if (!firstScan && findSensor != tachSensors.end())
            {
                bool found = false;
                for (auto it = sensorsChanged->begin();
                     it != sensorsChanged->end(); it++)
                {
                    if (it->ends_with(findSensor->second->name))
                    {
                        sensorsChanged->erase(it);
                        findSensor->second = nullptr;
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    continue;
                }
            }
            std::vector<thresholds::Threshold> sensorThresholds;
            if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
            {
                std::cerr << "error populating thresholds for " << sensorName
                          << "\n";
            }

            auto presenceConfig =
                sensorData->find(cfgIntf + std::string(".Presence"));

            std::unique_ptr<PresenceSensor> presenceSensor(nullptr);

            // presence sensors are optional
            if (presenceConfig != sensorData->end())
            {
                auto findPolarity = presenceConfig->second.find("Polarity");
                auto findPinName = presenceConfig->second.find("PinName");

                if (findPinName == presenceConfig->second.end() ||
                    findPolarity == presenceConfig->second.end())
                {
                    std::cerr << "Malformed Presence Configuration\n";
                }
                else
                {
                    bool inverted =
                        std::get<std::string>(findPolarity->second) == "Low";
                    if (const auto* pinName =
                            std::get_if<std::string>(&findPinName->second))
                    {
                        presenceSensor = std::make_unique<PresenceSensor>(
                            *pinName, inverted, io, sensorName);
                    }
                    else
                    {
                        std::cerr << "Malformed Presence pinName for sensor "
                                  << sensorName << " \n";
                    }
                }
            }
            std::optional<RedundancySensor>* redundancy = nullptr;
            if (fanType == FanTypes::aspeed)
            {
                redundancy = &systemRedundancy;
            }

            PowerState powerState = getPowerState(baseConfiguration->second);

            constexpr double defaultMaxReading = 25000;
            constexpr double defaultMinReading = 0;
            std::pair<double, double> limits =
                std::make_pair(defaultMinReading, defaultMaxReading);

            auto connector =
                sensorData->find(cfgIntf + std::string(".Connector"));

            std::optional<std::string> led;
            std::string pwmName;
            fs::path pwmPath;

            // The Mutable parameter is optional, defaulting to false
            bool isValueMutable = false;
            if (connector != sensorData->end())
            {
                auto findPwm = connector->second.find("Pwm");
                if (findPwm != connector->second.end())
                {
                    size_t pwm = std::visit(VariantToUnsignedIntVisitor(),
                                            findPwm->second);
                    if (!findPwmPath(directory, pwm, pwmPath))
                    {
                        std::cerr << "Connector for " << sensorName
                                  << " no pwm channel found!\n";
                        continue;
                    }

                    fs::path pwmEnableFile =
                        "pwm" + std::to_string(pwm + 1) + "_enable";
                    fs::path enablePath = pwmPath.parent_path() / pwmEnableFile;
                    enablePwm(enablePath);

                    /* use pwm name override if found in configuration else
                     * use default */
                    auto findOverride = connector->second.find("PwmName");
                    if (findOverride != connector->second.end())
                    {
                        pwmName = std::visit(VariantToStringVisitor(),
                                             findOverride->second);
                    }
                    else
                    {
                        pwmName = "Pwm_" + std::to_string(pwm + 1);
                    }

                    // Check PWM sensor mutability
                    auto findMutable = connector->second.find("Mutable");
                    if (findMutable != connector->second.end())
                    {
                        const auto* ptrMutable =
                            std::get_if<bool>(&(findMutable->second));
                        if (ptrMutable != nullptr)
                        {
                            isValueMutable = *ptrMutable;
                        }
                    }
                }
                else
                {
                    std::cerr << "Connector for " << sensorName
                              << " missing pwm!\n";
                }

                auto findLED = connector->second.find("LED");
                if (findLED != connector->second.end())
                {
                    const auto* ledName =
                        std::get_if<std::string>(&(findLED->second));
                    if (ledName == nullptr)
                    {
                        std::cerr << "Wrong format for LED of " << sensorName
                                  << "\n";
                    }
                    else
                    {
                        led = *ledName;
                    }
                }
            }

            findLimits(limits, baseConfiguration);

            enableFanInput(path);

            auto& tachSensor = tachSensors[sensorName];
            tachSensor = nullptr;
            tachSensor = std::make_shared<TachSensor>(
                path.string(), baseType, objectServer, dbusConnection,
                std::move(presenceSensor), redundancy, io, sensorName,
                std::move(sensorThresholds), *interfacePath, limits, powerState,
                led);
            tachSensor->setupRead();

            if (!pwmPath.empty() && fs::exists(pwmPath) &&
                (pwmSensors.count(pwmPath) == 0U))
            {
                pwmSensors[pwmPath] = std::make_unique<PwmSensor>(
                    pwmName, pwmPath, dbusConnection, objectServer,
                    *interfacePath, "Fan", isValueMutable);
            }
        }

        createRedundancySensor(tachSensors, dbusConnection, objectServer);
        });
    getter->getConfiguration(
        std::vector<std::string>{sensorTypes.begin(), sensorTypes.end()},
        retries);
}

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");
    objectServer.add_manager("/xyz/openbmc_project/inventory");
    systemBus->request_name("xyz.openbmc_project.FanSensor");
    boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>
        tachSensors;
    boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
        pwmSensors;
    auto sensorsChanged =
        std::make_shared<boost::container::flat_set<std::string>>();

    boost::asio::post(io, [&]() {
        createSensors(io, objectServer, tachSensors, pwmSensors, systemBus,
                      nullptr);
    });

    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());
        // this implicitly cancels the timer
        filterTimer.expires_after(std::chrono::seconds(1));

        filterTimer.async_wait([&](const boost::system::error_code& ec) {
            if (ec == boost::asio::error::operation_aborted)
            {
                /* we were canceled*/
                return;
            }
            if (ec)
            {
                std::cerr << "timer error\n";
                return;
            }
            createSensors(io, objectServer, tachSensors, pwmSensors, systemBus,
                          sensorsChanged, 5);
        });
    };

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

    // redundancy sensor
    std::function<void(sdbusplus::message_t&)> redundancyHandler =
        [&tachSensors, &systemBus, &objectServer](sdbusplus::message_t&) {
        createRedundancySensor(tachSensors, systemBus, objectServer);
    };
    auto match = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*systemBus),
        "type='signal',member='PropertiesChanged',path_namespace='" +
            std::string(inventoryPath) + "',arg0namespace='" +
            redundancyConfiguration + "'",
        std::move(redundancyHandler));
    matches.emplace_back(std::move(match));

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