#include <attn/attn_common.hpp>
#include <attn/attn_dbus.hpp>
#include <attn/attn_logging.hpp>
#include <util/dbus.hpp>
#include <util/trace.hpp>

#include <string>
#include <vector>

namespace attn
{

/** @brief Create a dbus method */
int dbusMethod(const std::string& i_path, const std::string& i_interface,
               const std::string& i_function, sdbusplus::message_t& o_method)
{
    int rc = RC_DBUS_ERROR; // assume error

    try
    {
        auto bus = sdbusplus::bus::new_system(); // using system dbus

        // we need to find the service implementing the interface
        util::dbus::DBusService service;

        if (0 == util::dbus::findService(i_interface, i_path, service))
        {
            // return the method
            o_method =
                bus.new_method_call(service.c_str(), i_path.c_str(),
                                    i_interface.c_str(), i_function.c_str());

            rc = RC_SUCCESS;
        }
        else
        {
            // This trace will be picked up in event log
            trace::inf("dbusMethod service not found");
            trace::inf(i_path.c_str());
            trace::inf(i_interface.c_str());
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        trace::err("dbusMethod exception");
        trace::err(e.what());
    }

    return rc;
}

/** @brief Create a PEL from raw PEL data */
void createPelRaw(const std::vector<uint8_t>& i_buffer)
{
    // Create FFDC file from buffer data
    util::FFDCFile pelFile{util::FFDCFormat::Text};
    auto fd = pelFile.getFileDescriptor();

    auto filePath = pelFile.getPath(); // path to ffdc file

    size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
    if (i_buffer.size() != numBytes)
    {
        trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
                   i_buffer.size());
    }

    lseek(fd, 0, SEEK_SET);

    // Additional data for log
    std::map<std::string, std::string> additional;
    additional.emplace("RAWPEL", filePath.string());
    additional.emplace("_PID", std::to_string(getpid()));

    // dbus specifics
    constexpr auto interface = "xyz.openbmc_project.Logging.Create";
    constexpr auto function  = "Create";

    sdbusplus::message_t method;

    if (0 == dbusMethod(pathLogging, interface, function, method))
    {
        try
        {
            // append additional dbus call parameters
            method.append(eventPelTerminate, levelPelError, additional);

            // using system dbus, no reply
            auto bus = sdbusplus::bus::new_system();
            bus.call_noreply(method);
        }
        catch (const sdbusplus::exception::SdBusError& e)
        {
            trace::err("createPelRaw exception");
            trace::err(e.what());
        }
    }
}

/** @brief Get file descriptor of exisitng PEL */
int getPel(const uint32_t i_pelId)
{
    // GetPEL returns file descriptor (int)
    int fd = -1;

    // dbus specifics
    constexpr auto interface = "org.open_power.Logging.PEL";
    constexpr auto function  = "GetPEL";

    sdbusplus::message_t method;

    if (0 == dbusMethod(pathLogging, interface, function, method))
    {
        try
        {
            // additional dbus call parameters
            method.append(i_pelId);

            // using system dbus
            auto bus      = sdbusplus::bus::new_system();
            auto response = bus.call(method);

            // reply will be a unix file descriptor
            sdbusplus::message::unix_fd reply;

            // parse dbus response into reply
            response.read(reply);

            fd = dup(reply); // need to copy (dup) the file descriptor
        }
        catch (const sdbusplus::exception::SdBusError& e)
        {
            trace::err("getPel exception");
            trace::err(e.what());
        }
    }

    return fd; // file descriptor or -1
}

} // namespace attn
