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

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/asio/post.hpp>
#include <boost/container/flat_set.hpp>
#include <cold_redundancy.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/asio/sd_event.hpp>
#include <sdbusplus/bus/match.hpp>

#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <regex>

namespace
{
constexpr const std::array<const char*, 1> psuInterfaceTypes = {
    "xyz.openbmc_project.Configuration.pmbus"};
std::string inventoryPath = std::string(INVENTORY_OBJ_PATH) + "/system";
const constexpr char* eventPath = "/xyz/openbmc_project/State/Decorator";
std::vector<std::unique_ptr<PowerSupply>> powerSupplies;
} // namespace

ColdRedundancy::ColdRedundancy(
    boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
    std::shared_ptr<sdbusplus::asio::connection>& systemBus) :
    filterTimer(io),
    systemBus(systemBus)
{
    post(io,
         [this, &io, &objectServer, &systemBus]() { createPSU(systemBus); });
    std::function<void(sdbusplus::message_t&)> eventHandler =
        [this, &io, &objectServer, &systemBus](sdbusplus::message_t& message) {
        if (message.is_method_error())
        {
            std::cerr << "callback method error\n";
            return;
        }
        filterTimer.expires_after(std::chrono::seconds(1));
        filterTimer.async_wait([this, &io, &objectServer, &systemBus](
                                   const boost::system::error_code& ec) {
            if (ec == boost::asio::error::operation_aborted)
            {
                return;
            }
            else if (ec)
            {
                std::cerr << "timer error\n";
            }
            createPSU(systemBus);
        });
    };

    std::function<void(sdbusplus::message_t&)> eventCollect =
        [&](sdbusplus::message_t& message) {
        std::string objectName;
        boost::container::flat_map<std::string, std::variant<bool>> values;
        std::string path = message.get_path();
        std::size_t slantingPos = path.find_last_of("/\\");
        if ((slantingPos == std::string::npos) ||
            ((slantingPos + 1) >= path.size()))
        {
            std::cerr << "Unable to get PSU state name from path\n";
            return;
        }
        std::string statePSUName = path.substr(slantingPos + 1);

        std::size_t hypenPos = statePSUName.find("_");
        if (hypenPos == std::string::npos)
        {
            std::cerr << "Unable to get PSU name from PSU path\n";
            return;
        }
        std::string psuName = statePSUName.substr(0, hypenPos);

        try
        {
            message.read(objectName, values);
        }
        catch (const sdbusplus::exception_t& e)
        {
            std::cerr << "Failed to read message from PSU Event\n";
            return;
        }

        for (auto& psu : powerSupplies)
        {
            if (psu->name != psuName)
            {
                continue;
            }

            std::string psuEventName = "functional";
            auto findEvent = values.find(psuEventName);
            if (findEvent != values.end())
            {
                bool* functional = std::get_if<bool>(&(findEvent->second));
                if (functional == nullptr)
                {
                    std::cerr << "Unable to get valid functional status\n";
                    continue;
                }
                if (*functional)
                {
                    psu->state = CR::PSUState::normal;
                }
                else
                {
                    psu->state = CR::PSUState::acLost;
                }
            }
        }
    };

    using namespace sdbusplus::bus::match::rules;
    for (const char* type : psuInterfaceTypes)
    {
        auto match = std::make_unique<sdbusplus::bus::match_t>(
            static_cast<sdbusplus::bus_t&>(*systemBus),
            type::signal() + member("PropertiesChanged") +
                path_namespace(inventoryPath) + arg0namespace(type),
            eventHandler);
        matches.emplace_back(std::move(match));
    }

    for (const char* eventType : psuEventInterface)
    {
        auto eventMatch = std::make_unique<sdbusplus::bus::match_t>(
            static_cast<sdbusplus::bus_t&>(*systemBus),
            type::signal() + member("PropertiesChanged") +
                path_namespace(eventPath) + arg0namespace(eventType),
            eventCollect);
        matches.emplace_back(std::move(eventMatch));
    }
}

static const constexpr int psuDepth = 3;
// Check PSU information from entity-manager D-Bus interface and use the bus
// address to create PSU Class for cold redundancy.
void ColdRedundancy::createPSU(
    std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    numberOfPSU = 0;
    powerSupplies.clear();

    // call mapper to get matched obj paths
    conn->async_method_call(
        [this, &conn](const boost::system::error_code ec,
                      CR::GetSubTreeType subtree) {
        if (ec)
        {
            std::cerr << "Exception happened when communicating to "
                         "ObjectMapper\n";
            return;
        }
        for (const auto& object : subtree)
        {
            std::string pathName = object.first;
            for (const auto& serviceIface : object.second)
            {
                std::string serviceName = serviceIface.first;
                for (const auto& interface : serviceIface.second)
                {
                    // only get property of matched interface
                    bool isIfaceMatched = false;
                    for (const auto& type : psuInterfaceTypes)
                    {
                        if (type == interface)
                        {
                            isIfaceMatched = true;
                            break;
                        }
                    }
                    if (!isIfaceMatched)
                        continue;

                    conn->async_method_call(
                        [this, &conn,
                         interface](const boost::system::error_code ec,
                                    CR::PropertyMapType propMap) {
                        if (ec)
                        {
                            std::cerr << "Exception happened when get all "
                                         "properties\n";
                            return;
                        }

                        auto configName =
                            std::get_if<std::string>(&propMap["Name"]);
                        if (configName == nullptr)
                        {
                            std::cerr << "error finding necessary "
                                         "entry in configuration\n";
                            return;
                        }

                        auto configBus = std::get_if<uint64_t>(&propMap["Bus"]);
                        auto configAddress =
                            std::get_if<uint64_t>(&propMap["Address"]);

                        if (configBus == nullptr || configAddress == nullptr)
                        {
                            std::cerr << "error finding necessary "
                                         "entry in configuration\n";
                            return;
                        }
                        for (auto& psu : powerSupplies)
                        {
                            if ((static_cast<uint8_t>(*configBus) ==
                                 psu->bus) &&
                                (static_cast<uint8_t>(*configAddress) ==
                                 psu->address))
                            {
                                return;
                            }
                        }

                        uint8_t order = 0;

                        powerSupplies.emplace_back(
                            std::make_unique<PowerSupply>(
                                *configName, static_cast<uint8_t>(*configBus),
                                static_cast<uint8_t>(*configAddress), order,
                                conn));

                        numberOfPSU++;
                        std::vector<uint8_t> orders = {};
                        for (auto& psu : powerSupplies)
                        {
                            orders.push_back(psu->order);
                        }
                    },
                        serviceName.c_str(), pathName.c_str(),
                        "org.freedesktop.DBus.Properties", "GetAll", interface);
                }
            }
        }
    },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
        "/xyz/openbmc_project/inventory/system", psuDepth, psuInterfaceTypes);
}

PowerSupply::PowerSupply(
    std::string& name, uint8_t bus, uint8_t address, uint8_t order,
    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection) :
    name(name),
    bus(bus), address(address), order(order)
{
    CR::getPSUEvent(dbusConnection, name, state);
}
