/*
// Copyright (c) 2018 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 "ChassisIntrusionSensor.hpp"
#include "Utils.hpp"

#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <phosphor-logging/lg2.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 <charconv>
#include <chrono>
#include <cstdint>
#include <ctime>
#include <exception>
#include <filesystem>
#include <fstream>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <system_error>
#include <utility>
#include <variant>
#include <vector>

static constexpr bool debug = false;

static constexpr const char* sensorType = "ChassisIntrusionSensor";
static constexpr const char* nicType = "NIC";
static constexpr auto nicTypes{std::to_array<const char*>({nicType})};

static const std::map<std::string, std::string> compatibleHwmonNames = {
    {"Aspeed2600_Hwmon", "intrusion0_alarm"}
    // Add compatible strings here for new hwmon intrusion detection
    // drivers that have different hwmon names but would also like to
    // use the available Hwmon class.
};

static void createSensorsFromConfig(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objServer,
    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
    std::shared_ptr<ChassisIntrusionSensor>& pSensor)
{
    // find matched configuration according to sensor type
    ManagedObjectType sensorConfigurations;
    bool useCache = false;

    if (!getSensorConfiguration(sensorType, dbusConnection,
                                sensorConfigurations, useCache))
    {
        lg2::error("error communicating to entity manager");
        return;
    }

    const SensorData* sensorData = nullptr;
    const std::pair<std::string, SensorBaseConfigMap>* baseConfiguration =
        nullptr;

    for (const auto& [path, cfgData] : sensorConfigurations)
    {
        baseConfiguration = nullptr;
        sensorData = &cfgData;

        // match sensor type
        auto sensorBase = sensorData->find(configInterfaceName(sensorType));
        if (sensorBase == sensorData->end())
        {
            lg2::error("error finding base configuration");
            continue;
        }

        baseConfiguration = &(*sensorBase);

        // Rearm defaults to "Automatic" mode
        bool autoRearm = true;
        auto findRearm = baseConfiguration->second.find("Rearm");
        if (findRearm != baseConfiguration->second.end())
        {
            std::string rearmStr = std::get<std::string>(findRearm->second);
            if (rearmStr != "Automatic" && rearmStr != "Manual")
            {
                lg2::error("Wrong input for Rearm parameter");
                continue;
            }
            autoRearm = (rearmStr == "Automatic");
        }

        // judge class, "Gpio", "Hwmon" or "I2C"
        auto findClass = baseConfiguration->second.find("Class");
        if (findClass != baseConfiguration->second.end())
        {
            auto classString = std::get<std::string>(findClass->second);
            if (classString == "Gpio")
            {
                auto findGpioPolarity =
                    baseConfiguration->second.find("GpioPolarity");

                if (findGpioPolarity == baseConfiguration->second.end())
                {
                    lg2::error("error finding gpio polarity in configuration");
                    continue;
                }

                try
                {
                    bool gpioInverted =
                        (std::get<std::string>(findGpioPolarity->second) ==
                         "Low");
                    pSensor = std::make_shared<ChassisIntrusionGpioSensor>(
                        autoRearm, io, objServer, gpioInverted);
                    pSensor->start();
                    if (debug)
                    {
                        lg2::info(
                            "find chassis intrusion sensor polarity inverted flag is '{GPIO_INVERTED}'",
                            "GPIO_INVERTED", gpioInverted);
                    }
                    return;
                }
                catch (const std::bad_variant_access& e)
                {
                    lg2::error("invalid value for gpio info in config.");
                    continue;
                }
                catch (const std::exception& e)
                {
                    lg2::error(
                        "error creating chassis intrusion gpio sensor: '{ERROR}'",
                        "ERROR", e);
                    continue;
                }
            }
            // If class string contains Hwmon string
            else if (classString.find("Hwmon") != std::string::npos)
            {
                std::string hwmonName;
                std::map<std::string, std::string>::const_iterator
                    compatIterator = compatibleHwmonNames.find(classString);

                if (compatIterator == compatibleHwmonNames.end())
                {
                    lg2::error("Hwmon Class string is not supported");
                    continue;
                }

                hwmonName = compatIterator->second;

                try
                {
                    pSensor = std::make_shared<ChassisIntrusionHwmonSensor>(
                        autoRearm, io, objServer, hwmonName);
                    pSensor->start();
                    return;
                }
                catch (const std::exception& e)
                {
                    lg2::error(
                        "error creating chassis intrusion hwmon sensor: '{ERROR}'",
                        "ERROR", e);
                    continue;
                }
            }
            else
            {
                auto findBus = baseConfiguration->second.find("Bus");
                auto findAddress = baseConfiguration->second.find("Address");
                if (findBus == baseConfiguration->second.end() ||
                    findAddress == baseConfiguration->second.end())
                {
                    lg2::error("error finding bus or address in configuration");
                    continue;
                }
                try
                {
                    int busId = std::get<uint64_t>(findBus->second);
                    int slaveAddr = std::get<uint64_t>(findAddress->second);
                    pSensor = std::make_shared<ChassisIntrusionPchSensor>(
                        autoRearm, io, objServer, busId, slaveAddr);
                    pSensor->start();
                    if (debug)
                    {
                        lg2::info(
                            "find matched bus '{BUS}', matched slave addr '{ADDR}'",
                            "BUS", busId, "ADDR", slaveAddr);
                    }
                    return;
                }
                catch (const std::bad_variant_access& e)
                {
                    lg2::error("invalid value for bus or address in config.");
                    continue;
                }
                catch (const std::exception& e)
                {
                    lg2::error(
                        "error creating chassis intrusion pch sensor: '{ERROR}'",
                        "ERROR", e);
                    continue;
                }
            }
        }
    }

    lg2::error("Can't find matched I2C, GPIO or Hwmon configuration");

    // Make sure nothing runs when there's failure in configuration for the
    // sensor after rescan
    if (pSensor)
    {
        lg2::error("Reset the occupied sensor pointer");
        pSensor = nullptr;
    }
}

static constexpr bool debugLanLeash = false;
boost::container::flat_map<int, bool> lanStatusMap;
boost::container::flat_map<int, std::string> lanInfoMap;
boost::container::flat_map<std::string, int> pathSuffixMap;

static void getNicNameInfo(
    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
{
    auto getter = std::make_shared<GetSensorConfiguration>(
        dbusConnection, [](const ManagedObjectType& sensorConfigurations) {
            // Get NIC name and save to map
            lanInfoMap.clear();
            for (const auto& [path, cfgData] : sensorConfigurations)
            {
                const std::pair<std::string, SensorBaseConfigMap>*
                    baseConfiguration = nullptr;

                // find base configuration
                auto sensorBase = cfgData.find(configInterfaceName(nicType));
                if (sensorBase == cfgData.end())
                {
                    continue;
                }
                baseConfiguration = &(*sensorBase);

                auto findEthIndex = baseConfiguration->second.find("EthIndex");
                auto findName = baseConfiguration->second.find("Name");

                if (findEthIndex != baseConfiguration->second.end() &&
                    findName != baseConfiguration->second.end())
                {
                    const auto* pEthIndex =
                        std::get_if<uint64_t>(&findEthIndex->second);
                    const auto* pName =
                        std::get_if<std::string>(&findName->second);
                    if (pEthIndex != nullptr && pName != nullptr)
                    {
                        lanInfoMap[*pEthIndex] = *pName;
                        if (debugLanLeash)
                        {
                            lg2::info("find name of eth{ETH_INDEX} is '{NAME}'",
                                      "ETH_INDEX", *pEthIndex, "NAME", *pName);
                        }
                    }
                }
            }

            if (lanInfoMap.empty())
            {
                lg2::error("can't find matched NIC name.");
            }
        });

    getter->getConfiguration(
        std::vector<std::string>{nicTypes.begin(), nicTypes.end()});
}

static void processLanStatusChange(sdbusplus::message_t& message)
{
    const std::string& pathName = message.get_path();
    std::string interfaceName;
    SensorBaseConfigMap properties;
    message.read(interfaceName, properties);

    auto findStateProperty = properties.find("OperationalState");
    if (findStateProperty == properties.end())
    {
        return;
    }
    std::string* pState =
        std::get_if<std::string>(&(findStateProperty->second));
    if (pState == nullptr)
    {
        lg2::error("invalid OperationalState");
        return;
    }

    bool newLanConnected = (*pState == "routable" || *pState == "carrier" ||
                            *pState == "degraded");

    // get ethNum from path. /org/freedesktop/network1/link/_32 for eth0
    size_t pos = pathName.find("/_");
    if (pos == std::string::npos || pathName.length() <= pos + 2)
    {
        lg2::error("unexpected path name '{NAME}'", "NAME", pathName);
        return;
    }
    std::string suffixStr = pathName.substr(pos + 2);

    auto findEthNum = pathSuffixMap.find(suffixStr);
    if (findEthNum == pathSuffixMap.end())
    {
        lg2::error("unexpected eth for suffixStr '{SUFFIX}'", "SUFFIX",
                   suffixStr);
        return;
    }
    int ethNum = findEthNum->second;

    // get lan status from map
    auto findLanStatus = lanStatusMap.find(ethNum);
    if (findLanStatus == lanStatusMap.end())
    {
        lg2::error("unexpected eth{ETH_INDEX} is lanStatusMap", "ETH_INDEX",
                   ethNum);
        return;
    }
    bool oldLanConnected = findLanStatus->second;

    // get lan info from map
    std::string lanInfo;
    if (!lanInfoMap.empty())
    {
        auto findLanInfo = lanInfoMap.find(ethNum);
        if (findLanInfo == lanInfoMap.end())
        {
            lg2::error("unexpected eth{ETH_INDEX} is lanInfoMap", "ETH_INDEX",
                       ethNum);
        }
        else
        {
            lanInfo = "(" + findLanInfo->second + ")";
        }
    }

    if (debugLanLeash)
    {
        lg2::info(
            "ethNum = {ETH_INDEX}, state = {LAN_STATUS}, oldLanConnected = {OLD_LAN_CONNECTED}, "
            "newLanConnected = {NEW_LAN_CONNECTED}",
            "ETH_INDEX", ethNum, "LAN_STATUS", *pState, "OLD_LAN_CONNECTED",
            (oldLanConnected ? "true" : "false"), "NEW_LAN_CONNECTED",
            (newLanConnected ? "true" : "false"));
    }

    if (oldLanConnected != newLanConnected)
    {
        std::string strEthNum = "eth" + std::to_string(ethNum) + lanInfo;
        const auto* strState = newLanConnected ? "connected" : "lost";
        const auto* strMsgId =
            newLanConnected ? "OpenBMC.0.1.LanRegained" : "OpenBMC.0.1.LanLost";

        lg2::info("'{ETH_INFO}' LAN leash '{LAN_STATUS}'", "ETH_INFO",
                  strEthNum, "LAN_STATUS", strState, "REDFISH_MESSAGE_ID",
                  strMsgId, "REDFISH_MESSAGE_ARGS", strEthNum);

        lanStatusMap[ethNum] = newLanConnected;
    }
}

/** @brief Initialize the lan status.
 *
 * @return true on success and false on failure
 */
static bool initializeLanStatus(
    const std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    // init lan port name from configuration
    getNicNameInfo(conn);

    // get eth info from sysfs
    std::vector<std::filesystem::path> files;
    if (!findFiles(std::filesystem::path("/sys/class/net/"),
                   R"(eth\d+/ifindex)", files))
    {
        lg2::error("No eth in system");
        return false;
    }

    // iterate through all found eth files, and save ifindex
    for (const std::filesystem::path& fileName : files)
    {
        if (debugLanLeash)
        {
            lg2::info("Reading '{NAME}'", "NAME", fileName);
        }
        std::ifstream sysFile(fileName);
        if (!sysFile.good())
        {
            lg2::error("Failure reading '{NAME}'", "NAME", fileName);
            continue;
        }
        std::string line;
        getline(sysFile, line);
        const uint8_t ifindex = std::stoi(line);
        // pathSuffix is ASCII of ifindex
        const std::string& pathSuffix = std::to_string(ifindex + 30);

        // extract ethNum
        const std::string& fileStr = fileName.string();
        const int pos = fileStr.find("eth");
        const std::string& ethNumStr = fileStr.substr(pos + 3);
        int ethNum = 0;
        std::from_chars_result r = std::from_chars(
            ethNumStr.data(), ethNumStr.data() + ethNumStr.size(), ethNum);
        if (r.ec != std::errc())
        {
            lg2::error("invalid ethNum string: '{ETH_INDEX}'", "ETH_INDEX",
                       ethNumStr);
            continue;
        }

        // save pathSuffix
        pathSuffixMap[pathSuffix] = ethNum;
        if (debugLanLeash)
        {
            lg2::info(
                "ethNum = {ETH_INDEX}, ifindex = {LINE}, pathSuffix = {PATH}",
                "ETH_INDEX", ethNum, "LINE", line, "PATH", pathSuffix);
        }

        // init lan connected status from networkd
        conn->async_method_call(
            [ethNum](boost::system::error_code ec,
                     const std::variant<std::string>& property) {
                lanStatusMap[ethNum] = false;
                if (ec)
                {
                    lg2::error("Error reading init status of eth{ETH_INDEX}",
                               "ETH_INDEX", ethNum);
                    return;
                }
                const std::string* pState = std::get_if<std::string>(&property);
                if (pState == nullptr)
                {
                    lg2::error("Unable to read lan status value");
                    return;
                }
                bool isLanConnected =
                    (*pState == "routable" || *pState == "carrier" ||
                     *pState == "degraded");
                if (debugLanLeash)
                {
                    lg2::info(
                        "ethNum = {ETH_INDEX}, init LAN status = {STATUS}",
                        "ETH_INDEX", ethNum, "STATUS",
                        (isLanConnected ? "true" : "false"));
                }
                lanStatusMap[ethNum] = isLanConnected;
            },
            "org.freedesktop.network1",
            "/org/freedesktop/network1/link/_" + pathSuffix,
            "org.freedesktop.DBus.Properties", "Get",
            "org.freedesktop.network1.Link", "OperationalState");
    }
    return true;
}

int main()
{
    std::shared_ptr<ChassisIntrusionSensor> intrusionSensor;

    // setup connection to dbus
    boost::asio::io_context io;
    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);

    // setup object server, define interface
    systemBus->request_name("xyz.openbmc_project.IntrusionSensor");

    sdbusplus::asio::object_server objServer(systemBus, true);

    objServer.add_manager("/xyz/openbmc_project/Chassis");

    createSensorsFromConfig(io, objServer, systemBus, intrusionSensor);

    // callback to handle configuration change
    boost::asio::steady_timer filterTimer(io);
    std::function<void(sdbusplus::message_t&)> eventHandler =
        [&](sdbusplus::message_t& message) {
            if (message.is_method_error())
            {
                lg2::error("callback method error");
                return;
            }
            // 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)
                {
                    // timer was cancelled
                    return;
                }
                lg2::info("rescan due to configuration change");
                createSensorsFromConfig(io, objServer, systemBus,
                                        intrusionSensor);
            });
        };

    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
        setupPropertiesChangedMatches(
            *systemBus, std::to_array<const char*>({sensorType}), eventHandler);

    if (initializeLanStatus(systemBus))
    {
        // add match to monitor lan status change
        sdbusplus::bus::match_t lanStatusMatch(
            static_cast<sdbusplus::bus_t&>(*systemBus),
            "type='signal', member='PropertiesChanged',"
            "arg0namespace='org.freedesktop.network1.Link'",
            [](sdbusplus::message_t& msg) { processLanStatusChange(msg); });

        // add match to monitor entity manager signal about nic name config
        // change
        sdbusplus::bus::match_t lanConfigMatch(
            static_cast<sdbusplus::bus_t&>(*systemBus),
            "type='signal', member='PropertiesChanged',path_namespace='" +
                std::string(inventoryPath) + "',arg0namespace='" +
                configInterfaceName(nicType) + "'",
            [&systemBus](sdbusplus::message_t& msg) {
                if (msg.is_method_error())
                {
                    lg2::error("callback method error");
                    return;
                }
                getNicNameInfo(systemBus);
            });
    }

    io.run();

    return 0;
}
