#include <phosphor-logging/elog.hpp>
#include <sdbusplus/exception.hpp>
#include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
#include "xyz/openbmc_project/Led/Mapper/error.hpp"
#include "elog-errors.hpp"
#include "fru-fault-monitor.hpp"
#include <phosphor-logging/elog-errors.hpp>
#include "xyz/openbmc_project/Common/error.hpp"

namespace phosphor
{
namespace led
{
namespace fru
{
namespace fault
{
namespace monitor
{

using namespace phosphor::logging;

constexpr auto MAPPER_BUSNAME   = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_OBJ_PATH  = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_IFACE     = "xyz.openbmc_project.ObjectMapper";
constexpr auto OBJMGR_IFACE     = "org.freedesktop.DBus.ObjectManager";
constexpr auto LED_GROUPS       = "/xyz/openbmc_project/led/groups/";
constexpr auto LOG_PATH         = "/xyz/openbmc_project/logging";
constexpr auto LOG_IFACE        = "xyz.openbmc_project.Logging.Entry";

using AssociationList = std::vector<std::tuple<
                        std::string, std::string, std::string>>;
using Attributes = sdbusplus::message::variant<bool,AssociationList>;
using AttributeName = std::string;
using AttributeMap = std::map<AttributeName, Attributes>;
using PropertyName = std::string;
using PropertyMap = std::map<PropertyName, AttributeMap>;
using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;

using Service = std::string;
using Path = std::string;
using Interface = std::string;
using Interfaces = std::vector<Interface>;
using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;

using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

using MethodErr  =
    sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
using ObjectNotFoundErr =
    sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
using InventoryPathErr =
    sdbusplus::xyz::openbmc_project::
    Led::Fru::Monitor::Error::InventoryPathError;

std::string getService(sdbusplus::bus::bus& bus,
                       const std::string& path)
{
    auto mapper = bus.new_method_call(MAPPER_BUSNAME,
                                      MAPPER_OBJ_PATH,
                                      MAPPER_IFACE, "GetObject");
    mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
    auto mapperResponseMsg = bus.call(mapper);
    if (mapperResponseMsg.is_method_error())
    {
        using namespace xyz::openbmc_project::Led::Mapper;
        elog<MethodErr>(
            MethodError::METHOD_NAME("GetObject"),
            MethodError::PATH(path.c_str()),
            MethodError::INTERFACE(
                OBJMGR_IFACE));
    }

    std::map<std::string, std::vector<std::string>> mapperResponse;
    try
    {
        mapperResponseMsg.read(mapperResponse);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        log<level::ERR>("Failed to parse getService mapper response",
                        entry("ERROR=%s", e.what()),
                        entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
        using namespace xyz::openbmc_project::Led::Mapper;
        elog<ObjectNotFoundErr>(
            ObjectNotFoundError::METHOD_NAME("GetObject"),
            ObjectNotFoundError::PATH(path.c_str()),
            ObjectNotFoundError::INTERFACE(
                OBJMGR_IFACE));
    }
    if (mapperResponse.empty())
    {
        using namespace xyz::openbmc_project::Led::Mapper;
        elog<ObjectNotFoundErr>(
            ObjectNotFoundError::METHOD_NAME("GetObject"),
            ObjectNotFoundError::PATH(path.c_str()),
            ObjectNotFoundError::INTERFACE(
                OBJMGR_IFACE));
    }

    return mapperResponse.cbegin()->first;
}

void action(sdbusplus::bus::bus& bus,
            const std::string& path,
            bool assert)
{
    std::string service;
    try
    {
        service = getService(bus, LED_GROUPS);
    }
    catch (MethodErr& e)
    {
        commit<MethodErr>();
        return;
    }
    catch (ObjectNotFoundErr& e)
    {
        commit<ObjectNotFoundErr>();
        return;
    }

    auto pos = path.rfind("/");
    if (pos == std::string::npos)
    {
        using namespace xyz::openbmc_project::Led::Fru::Monitor;
        report<InventoryPathErr>(
            InventoryPathError::PATH(
                path.c_str()));
        return;
    }
    auto unit = path.substr(pos + 1);

    std::string ledPath = LED_GROUPS +
                          unit + '_' + LED_FAULT;

    auto method =  bus.new_method_call(service.c_str(),
                                       ledPath.c_str(),
                                       "org.freedesktop.DBus.Properties",
                                       "Set");
    method.append("xyz.openbmc_project.Led.Group");
    method.append("Asserted");

    method.append(sdbusplus::message::variant<bool>(assert));
    bus.call_noreply(method);

    return;
}

void Add::created(sdbusplus::message::message& msg)
{
    auto bus = msg.get_bus();

    LogEntryMsg logEntry;
    try
    {
        msg.read(logEntry);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        log<level::ERR>("Failed to parse created message",
                        entry("ERROR=%s", e.what()),
                        entry("REPLY_SIG=%s", msg.get_signature()));
        return;
    }
    std::string objectPath(std::move(logEntry.first));

    std::size_t found = objectPath.find(ELOG_ENTRY);
    if (found == std::string::npos)
    {
        //Not a new error entry skip
        return;
    }
    auto iter = logEntry.second.find("org.openbmc.Associations");
    if (iter == logEntry.second.end())
    {
        return;
    }

    //Nothing else shows when a specific error log
    //has been created. Do it here.
    std::string message{objectPath + " created"};
    log<level::INFO>(message.c_str());

    auto attr = iter->second.find("associations");
    if (attr == iter->second.end())
    {
        return;
    }

    auto& assocs =
        sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
    if (assocs.empty())
    {
        //No associations skip
        return;
    }

    for (const auto& item : assocs)
    {
        if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
        {
            removeWatches.emplace_back(
                std::make_unique<Remove>(bus, std::get<2>(item)));
            action(bus, std::get<2>(item), true);
        }
    }

    return;
}

void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
{
    auto depth = 0;
    auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
                                          MAPPER_OBJ_PATH,
                                          MAPPER_IFACE,
                                          "GetSubTree");
    mapperCall.append("/");
    mapperCall.append(depth);
    mapperCall.append(std::vector<Interface>({LOG_IFACE}));

    auto mapperResponseMsg = bus.call(mapperCall);
    if (mapperResponseMsg.is_method_error())
    {
        using namespace xyz::openbmc_project::Led::Mapper;
        report<MethodErr>(
            MethodError::METHOD_NAME("GetSubTree"),
            MethodError::PATH(MAPPER_OBJ_PATH),
            MethodError::INTERFACE(
                OBJMGR_IFACE));
        return;
    }

    MapperResponseType mapperResponse;
    try
    {
        mapperResponseMsg.read(mapperResponse);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        log<level::ERR>("Failed to parse existing callouts subtree message",
                        entry("ERROR=%s", e.what()),
                        entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
        return;
    }
    if (mapperResponse.empty())
    {
        //No errors to process.
        return;
    }

    for (const auto& elem : mapperResponse)
    {
        auto method =  bus.new_method_call(elem.second.begin()->first.c_str(),
                                           elem.first.c_str(),
                                           "org.freedesktop.DBus.Properties",
                                           "Get");
        method.append("org.openbmc.Associations");
        method.append("associations");
        auto reply = bus.call(method);
        if (reply.is_method_error())
        {
            //do not stop, continue with next elog
            log<level::ERR>("Error in getting associations");
            continue;
        }

        sdbusplus::message::variant<AssociationList> assoc;
        try
        {
            reply.read(assoc);
        }
        catch (const sdbusplus::exception::SdBusError& e)
        {
            log<level::ERR>("Failed to parse existing callouts associations message",
                            entry("ERROR=%s", e.what()),
                            entry("REPLY_SIG=%s", reply.get_signature()));
            continue;
        }
        auto& assocs = assoc.get<AssociationList>();
        if (assocs.empty())
        {
            //no associations, skip
            continue;
        }

        for (const auto& item : assocs)
        {
            if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
            {
                removeWatches.emplace_back(
                    std::make_unique<Remove>(bus, std::get<2>(item)));
                action(bus, std::get<2>(item), true);
            }
        }
    }
}

void Remove::removed(sdbusplus::message::message& msg)
{
    auto bus = msg.get_bus();

    action(bus, inventoryPath, false);
    return;
}

}//namespace monitor
}//namespace fault
}//namespace fru
}//namespace led
}//namespace phosphor
