/*
// 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 "PresenceGpio.hpp"
#include "PwmSensor.hpp"
#include "TachSensor.hpp"
#include "Thresholds.hpp"
#include "Utils.hpp"
#include "VariantVisitors.hpp"

#include <boost/algorithm/string/replace.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/steady_timer.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.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/message.hpp>

#include <array>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <functional>
#include <ios>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <system_error>
#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},
    {"aspeed,ast2600-pwm-tach", FanTypes::aspeed},
    {"nuvoton,npcm750-pwm-fan", FanTypes::nuvoton},
    {"nuvoton,npcm845-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,
    boost::container::flat_map<std::string, std::weak_ptr<PresenceGpio>>&
        presenceGpios,
    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,
                                                 &presenceGpios,
                                                 &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)
                {
                    std::string deviceName =
                        fs::read_symlink(directory / "device").filename();

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

                    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 == addr)
                    {
                        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::shared_ptr<PresenceGpio> presenceGpio(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";
                    const auto* pinName =
                        std::get_if<std::string>(&findPinName->second);

                    if (pinName != nullptr)
                    {
                        auto findPresenceGpio = presenceGpios.find(*pinName);
                        if (findPresenceGpio != presenceGpios.end())
                        {
                            auto p = findPresenceGpio->second.lock();
                            if (p)
                            {
                                presenceGpio = p;
                            }
                        }
                        if (!presenceGpio)
                        {
                            auto findMonitorType =
                                presenceConfig->second.find("MonitorType");
                            bool polling = false;
                            if (findMonitorType != presenceConfig->second.end())
                            {
                                auto mType = std::get<std::string>(
                                    findMonitorType->second);
                                if (mType == "Polling")
                                {
                                    polling = true;
                                }
                                else if (mType != "Event")
                                {
                                    std::cerr
                                        << "Unsupported GPIO MonitorType of "
                                        << mType << " for " << sensorName
                                        << " (supported types: Polling, Event (default))\n";
                                }
                            }
                            try
                            {
                                if (polling)
                                {
                                    presenceGpio =
                                        std::make_shared<PollingPresenceGpio>(
                                            "Fan", sensorName, *pinName,
                                            inverted, io);
                                }
                                else
                                {
                                    presenceGpio =
                                        std::make_shared<EventPresenceGpio>(
                                            "Fan", sensorName, *pinName,
                                            inverted, io);
                                }
                                presenceGpios[*pinName] = presenceGpio;
                            }
                            catch (const std::system_error& e)
                            {
                                std::cerr
                                    << "Failed to create GPIO monitor object for "
                                    << *pinName << " / " << sensorName << ": "
                                    << e.what() << "\n";
                            }
                        }
                    }
                    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,
                presenceGpio, 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;
    boost::container::flat_map<std::string, std::weak_ptr<PresenceGpio>>
        presenceGpios;
    auto sensorsChanged =
        std::make_shared<boost::container::flat_set<std::string>>();

    boost::asio::post(io, [&]() {
        createSensors(io, objectServer, tachSensors, pwmSensors, presenceGpios,
                      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,
                              presenceGpios, 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;
}
