#include "config.h"

#include "systemintfcmds.hpp"

#include "host-cmd-manager.hpp"
#include "host-interface.hpp"

#include <cstring>
#include <ipmid-host/cmd.hpp>
#include <ipmid/api.hpp>

void register_netfn_app_functions() __attribute__((constructor));

using namespace sdbusplus::xyz::openbmc_project::Control::server;

// For accessing Host command manager
using cmdManagerPtr = std::unique_ptr<phosphor::host::command::Manager>;
extern cmdManagerPtr& ipmid_get_host_cmd_manager();

//-------------------------------------------------------------------
// Called by Host post response from Get_Message_Flags
//-------------------------------------------------------------------
ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
                               ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t)
{
    ipmi_ret_t rc = IPMI_CC_OK;

    struct oem_sel_timestamped oem_sel = {};
    *data_len = sizeof(struct oem_sel_timestamped);

    // either id[0] -or- id[1] can be filled in. We will use id[0]
    oem_sel.id[0] = SEL_OEM_ID_0;
    oem_sel.id[1] = SEL_OEM_ID_0;
    oem_sel.type = SEL_RECORD_TYPE_OEM;

    // Following 3 bytes are from IANA Manufactre_Id field. See below
    oem_sel.manuf_id[0] = 0x41;
    oem_sel.manuf_id[1] = 0xA7;
    oem_sel.manuf_id[2] = 0x00;

    // per IPMI spec NetFuntion for OEM
    oem_sel.netfun = 0x3A;

    // Read from the Command Manager queue. What gets returned is a
    // pair of <command, data> that can be directly used here
    auto hostCmd = ipmid_get_host_cmd_manager()->getNextCommand();
    oem_sel.cmd = hostCmd.first;
    oem_sel.data[0] = hostCmd.second;

    // All '0xFF' since unused.
    std::memset(&oem_sel.data[1], 0xFF, 3);

    // Pack the actual response
    std::memcpy(response, &oem_sel, *data_len);
    return rc;
}

//---------------------------------------------------------------------
// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded
// value of 0x0 to indicate Event Message Buffer is not supported
//-------------------------------------------------------------------
ipmi::RspType<uint8_t> ipmiAppGetMessageFlags()
{
    // From IPMI spec V2.0 for Get Message Flags Command :
    // bit:[1] from LSB : 1b = Event Message Buffer Full.
    // Return as 0 if Event Message Buffer is not supported,
    // or when the Event Message buffer is disabled.
    // This path is used to communicate messages to the host
    // from within the phosphor::host::command::Manager
    constexpr uint8_t setEventMsgBufferNotSupported = 0x0;
    return ipmi::responseSuccess(setEventMsgBufferNotSupported);
}

ipmi::RspType<bool,    // Receive Message Queue Interrupt Enabled
              bool,    // Event Message Buffer Full Interrupt Enabled
              bool,    // Event Message Buffer Enabled
              bool,    // System Event Logging Enabled
              uint1_t, // Reserved
              bool,    // OEM 0 enabled
              bool,    // OEM 1 enabled
              bool     // OEM 2 enabled
              >
    ipmiAppGetBMCGlobalEnable()
{
    return ipmi::responseSuccess(true, false, false, true, 0, false, false,
                                 false);
}

ipmi::RspType<> ipmiAppSetBMCGlobalEnable(
    ipmi::Context::ptr ctx, bool receiveMessageQueueInterruptEnabled,
    bool eventMessageBufferFullInterruptEnabled, bool eventMessageBufferEnabled,
    bool systemEventLogEnable, uint1_t reserved, bool OEM0Enabled,
    bool OEM1Enabled, bool OEM2Enabled)
{
    ipmi::ChannelInfo chInfo;

    if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Failed to get Channel Info",
            phosphor::logging::entry("CHANNEL=%d", ctx->channel));
        return ipmi::responseUnspecifiedError();
    }

    if (chInfo.mediumType !=
        static_cast<uint8_t>(ipmi::EChannelMediumType::systemInterface))
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Error - supported only in system interface");
        return ipmi::responseCommandNotAvailable();
    }

    // Recv Message Queue and SEL are enabled by default.
    // Event Message buffer are disabled by default (not supported).
    // Any request that try to change the mask will be rejected
    if (!receiveMessageQueueInterruptEnabled || !systemEventLogEnable ||
        eventMessageBufferFullInterruptEnabled || eventMessageBufferEnabled ||
        OEM0Enabled || OEM1Enabled || OEM2Enabled || reserved)
    {
        return ipmi::responseInvalidFieldRequest();
    }

    return ipmi::responseSuccess();
}

namespace
{
// Static storage to keep the object alive during process life
std::unique_ptr<phosphor::host::command::Host> host
    __attribute__((init_priority(101)));
std::unique_ptr<sdbusplus::server::manager_t> objManager
    __attribute__((init_priority(101)));
} // namespace

void register_netfn_app_functions()
{

    // <Read Event Message Buffer>
    ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL,
                           ipmi_app_read_event, SYSTEM_INTERFACE);

    // <Set BMC Global Enables>
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdSetBmcGlobalEnables,
                          ipmi::Privilege::Admin, ipmiAppSetBMCGlobalEnable);

    // <Get BMC Global Enables>
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetBmcGlobalEnables,
                          ipmi::Privilege::User, ipmiAppGetBMCGlobalEnable);

    // <Get Message Flags>
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetMessageFlags, ipmi::Privilege::Admin,
                          ipmiAppGetMessageFlags);

    // Create new xyz.openbmc_project.host object on the bus
    auto objPath = std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME + '0';

    std::unique_ptr<sdbusplus::asio::connection>& sdbusp =
        ipmid_get_sdbus_plus_handler();

    // Add sdbusplus ObjectManager.
    objManager = std::make_unique<sdbusplus::server::manager_t>(
        *sdbusp, CONTROL_HOST_OBJ_MGR);

    host = std::make_unique<phosphor::host::command::Host>(*sdbusp,
                                                           objPath.c_str());
    sdbusp->request_name(CONTROL_HOST_BUSNAME);

    return;
}
