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

#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <variant>

constexpr const char* fatalLedPath =
    "/xyz/openbmc_project/led/groups/status_critical";
constexpr const char* criticalLedPath =
    "/xyz/openbmc_project/led/groups/status_non_critical";
constexpr const char* warningLedPath =
    "/xyz/openbmc_project/led/groups/status_degraded";
constexpr const char* okLedPath = "/xyz/openbmc_project/led/groups/status_ok";

constexpr const char* ledIface = "xyz.openbmc_project.Led.Group";
constexpr const char* ledAssertProp = "Asserted";
constexpr const char* ledManagerBusname =
    "xyz.openbmc_project.LED.GroupManager";

std::unique_ptr<AssociationManager> associationManager;

enum class StatusSetting
{
    none,
    ok,
    warn,
    critical,
    fatal
};

constexpr const bool debug = false;

// final led state tracking
StatusSetting currentPriority = StatusSetting::none;

// maps of <object-path, <property, asserted>>
boost::container::flat_map<std::string,
                           boost::container::flat_map<std::string, bool>>
    fatalAssertMap;
boost::container::flat_map<std::string,
                           boost::container::flat_map<std::string, bool>>
    criticalAssertMap;
boost::container::flat_map<std::string,
                           boost::container::flat_map<std::string, bool>>
    warningAssertMap;

std::vector<std::string> assertedInMap(
    const boost::container::flat_map<
        std::string, boost::container::flat_map<std::string, bool>>& map)
{
    std::vector<std::string> ret;
    // if any of the properties are true, return true
    for (const auto& pair : map)
    {
        for (const auto& item : pair.second)
        {
            if (item.second)
            {
                ret.push_back(pair.first);
            }
        }
    }
    return ret;
}

void updateLedStatus(std::shared_ptr<sdbusplus::asio::connection>& conn,
                     bool forceRefresh = false)
{
    std::vector<std::string> fatalVector = assertedInMap(fatalAssertMap);
    bool fatal = fatalVector.size();

    std::vector<std::string> criticalVector = assertedInMap(criticalAssertMap);
    bool critical = criticalVector.size();

    std::vector<std::string> warningVector = assertedInMap(warningAssertMap);
    bool warn = warningVector.size();

    associationManager->setLocalAssociations(fatalVector, criticalVector,
                                             warningVector);

    StatusSetting last = currentPriority;
    std::vector<std::pair<std::string, std::variant<bool>>> ledsToSet;
    if (forceRefresh)
    {
        ledsToSet.push_back(std::make_pair(fatalLedPath, false));
        ledsToSet.push_back(std::make_pair(criticalLedPath, false));
        ledsToSet.push_back(std::make_pair(warningLedPath, false));
        ledsToSet.push_back(std::make_pair(okLedPath, false));
        for (const auto& ledPair : ledsToSet)
        {
            conn->async_method_call(
                [ledPair](const boost::system::error_code ec) {
                    if (ec)
                    {
                        std::cerr << "Cannot set " << ledPair.first << " to "
                                  << std::boolalpha
                                  << std::get<bool>(ledPair.second) << "\n";
                    }
                    if constexpr (debug)
                    {
                        std::cerr << "Set " << ledPair.first << " to "
                                  << std::boolalpha
                                  << std::get<bool>(ledPair.second) << "\n";
                    }
                },
                ledManagerBusname, ledPair.first,
                "org.freedesktop.DBus.Properties", "Set", ledIface,
                ledAssertProp, ledPair.second);
        }
    }
    if (fatal)
    {
        currentPriority = StatusSetting::fatal;
    }
    else if (critical)
    {
        currentPriority = StatusSetting::critical;
    }
    else if (warn)
    {
        currentPriority = StatusSetting::warn;
    }
    else
    {
        currentPriority = StatusSetting::ok;
    }

    if (last != currentPriority || forceRefresh)
    {
        switch (currentPriority)
        {
            case (StatusSetting::fatal):
            {
                ledsToSet.push_back(std::make_pair(fatalLedPath, true));
                ledsToSet.push_back(std::make_pair(criticalLedPath, false));
                ledsToSet.push_back(std::make_pair(warningLedPath, false));
                ledsToSet.push_back(std::make_pair(okLedPath, false));
                break;
            }
            case (StatusSetting::critical):
            {
                ledsToSet.push_back(std::make_pair(fatalLedPath, false));
                ledsToSet.push_back(std::make_pair(criticalLedPath, true));
                ledsToSet.push_back(std::make_pair(warningLedPath, false));
                ledsToSet.push_back(std::make_pair(okLedPath, false));
                break;
            }
            case (StatusSetting::warn):
            {
                ledsToSet.push_back(std::make_pair(fatalLedPath, false));
                ledsToSet.push_back(std::make_pair(criticalLedPath, false));
                ledsToSet.push_back(std::make_pair(warningLedPath, true));
                ledsToSet.push_back(std::make_pair(okLedPath, false));
                break;
            }
            case (StatusSetting::ok):
            {
                ledsToSet.push_back(std::make_pair(fatalLedPath, false));
                ledsToSet.push_back(std::make_pair(criticalLedPath, false));
                ledsToSet.push_back(std::make_pair(warningLedPath, false));
                ledsToSet.push_back(std::make_pair(okLedPath, true));
                break;
            }
        }
    }

    for (const auto& ledPair : ledsToSet)
    {
        conn->async_method_call(
            [ledPair](const boost::system::error_code ec) {
                if (ec)
                {
                    std::cerr << "Cannot set " << ledPair.first << " to "
                              << std::boolalpha
                              << std::get<bool>(ledPair.second) << "\n";
                }
                if constexpr (debug)
                {
                    std::cerr << "Set " << ledPair.first << " to "
                              << std::boolalpha
                              << std::get<bool>(ledPair.second) << "\n";
                }
            },
            ledManagerBusname, ledPair.first, "org.freedesktop.DBus.Properties",
            "Set", ledIface, ledAssertProp, ledPair.second);
    }
}

void createThresholdMatch(std::shared_ptr<sdbusplus::asio::connection>& conn)
{

    static sdbusplus::bus::match_t match(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',member='ThresholdAsserted'",
        [&conn](sdbusplus::message_t& message) {
            std::string sensorName;
            std::string thresholdInterface;
            std::string event;
            bool assert;
            double assertValue;

            try
            {
                message.read(sensorName, thresholdInterface, event, assert,
                             assertValue);
            }
            catch (sdbusplus::exception_t&)
            {
                return;
            }
            if constexpr (debug)
            {
                std::cerr << "Threshold callback: SensorName = " << sensorName
                          << ", Event = " << event << ", Asserted = " << assert
                          << "\n";
            }

            if (event == "CriticalAlarmLow")
            {
                criticalAssertMap[message.get_path()]["low"] = assert;
            }
            else if (event == "CriticalAlarmHigh")
            {
                criticalAssertMap[message.get_path()]["high"] = assert;
            }
            else if (event == "WarningAlarmLow")
            {
                warningAssertMap[message.get_path()]["low"] = assert;
            }
            else if (event == "WarningAlarmHigh")
            {
                warningAssertMap[message.get_path()]["high"] = assert;
            }

            associationManager->setSensorAssociations(
                assertedInMap(criticalAssertMap),
                assertedInMap(warningAssertMap));

            updateLedStatus(conn);
        });
}

void createAssociationMatch(std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    static sdbusplus::bus::match_t match(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',interface='org.freedesktop.DBus.Properties',"
        "arg0namespace='" +
            std::string(associationIface) + "'",
        [&conn](sdbusplus::message_t& message) {
            if (message.get_path() == rootPath)
            {
                return; // it's us
            }
            std::string objectName;
            boost::container::flat_map<std::string,
                                       std::variant<std::vector<Association>>>
                values;
            try
            {
                message.read(objectName, values);
            }
            catch (sdbusplus::exception_t&)
            {
                return;
            }

            if constexpr (debug)
            {
                std::cerr << "Association callback " << message.get_path()
                          << "\n";
            }

            auto findAssociations = values.find("Associations");
            if (findAssociations == values.end())
            {
                return;
            }
            const std::vector<Association>* associations =
                std::get_if<std::vector<Association>>(
                    &findAssociations->second);

            if (associations == nullptr)
            {
                std::cerr << "Illegal Association on " << message.get_path()
                          << "\n";
                return;
            }

            bool localWarning = false;
            bool localCritical = false;
            bool globalWarning = false;
            bool globalCritical = false;

            for (const auto& [forward, reverse, path] : *associations)
            {
                if (path == rootPath)
                {
                    globalWarning = globalWarning ? true : reverse == "warning";
                    globalCritical =
                        globalCritical ? true : reverse == "critical";

                    if constexpr (1)
                    {
                        std::cerr << "got global ";
                    }
                }
                else
                {
                    localWarning = localWarning ? true : reverse == "warning";
                    localCritical =
                        localCritical ? true : reverse == "critical";
                }
                if (globalCritical && localCritical)
                {
                    break;
                }
            }

            bool fatal = globalCritical && localCritical;
            bool critical = globalWarning && localCritical;
            bool warning = globalWarning && !critical;

            fatalAssertMap[message.get_path()]["association"] = fatal;
            criticalAssertMap[message.get_path()]["association"] = critical;
            warningAssertMap[message.get_path()]["association"] = warning;

            updateLedStatus(conn);
        });
}

int main(int argc, char** argv)
{
    boost::asio::io_service io;
    auto conn = std::make_shared<sdbusplus::asio::connection>(io);
    conn->request_name("xyz.openbmc_project.CallbackManager");
    sdbusplus::asio::object_server objServer(conn);
    std::shared_ptr<sdbusplus::asio::dbus_interface> rootIface =
        objServer.add_interface(rootPath,
                                "xyz.openbmc_project.CallbackManager");
    rootIface->register_method("RetriggerLEDUpdate",
                               [&conn]() { updateLedStatus(conn, true); });
    rootIface->initialize();

    std::shared_ptr<sdbusplus::asio::dbus_interface> inventoryIface =
        objServer.add_interface(rootPath, globalInventoryIface);
    inventoryIface->initialize();

    associationManager = std::make_unique<AssociationManager>(objServer, conn);

    createThresholdMatch(conn);
    createAssociationMatch(conn);
    updateLedStatus(conn);

    io.run();

    return 0;
}
