// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.

#include "config.h"

#include "hiomap.hpp"

#include <endian.h>
#include <host-ipmid/ipmid-api.h>
#include <string.h>
#include <systemd/sd-bus.h>

#include <fstream>
#include <functional>
#include <host-ipmid/ipmid-host-cmd-utils.hpp>
#include <host-ipmid/ipmid-host-cmd.hpp>
#include <iostream>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/exception.hpp>

using namespace sdbusplus;
using namespace phosphor::host::command;

static void register_openpower_hiomap_commands() __attribute__((constructor));

namespace openpower
{
namespace flash
{
constexpr auto BMC_EVENT_DAEMON_READY = 1 << 7;
constexpr auto BMC_EVENT_FLASH_CTRL_LOST = 1 << 6;
constexpr auto BMC_EVENT_WINDOW_RESET = 1 << 1;
constexpr auto BMC_EVENT_PROTOCOL_RESET = 1 << 0;

constexpr auto IPMI_CMD_HIOMAP_EVENT = 0x0f;

constexpr auto HIOMAPD_SERVICE = "xyz.openbmc_project.Hiomapd";
constexpr auto HIOMAPD_OBJECT = "/xyz/openbmc_project/Hiomapd";
constexpr auto HIOMAPD_IFACE = "xyz.openbmc_project.Hiomapd.Protocol";
constexpr auto HIOMAPD_IFACE_V2 = "xyz.openbmc_project.Hiomapd.Protocol.V2";

constexpr auto DBUS_IFACE_PROPERTIES = "org.freedesktop.DBus.Properties";

struct hiomap
{
    bus::bus *bus;

    /* Signals */
    bus::match::match *properties;
    bus::match::match *window_reset;
    bus::match::match *bmc_reboot;

    /* Protocol state */
    std::map<std::string, int> event_lookup;
    uint8_t bmc_events;
};

/* TODO: Replace get/put with packed structs and direct assignment */
template <typename T> static inline T get(void *buf)
{
    T t;
    memcpy(&t, buf, sizeof(t));
    return t;
}

template <typename T> static inline void put(void *buf, T &&t)
{
    memcpy(buf, &t, sizeof(t));
}

typedef ipmi_ret_t (*hiomap_command)(ipmi_request_t req, ipmi_response_t resp,
                                     ipmi_data_len_t data_len,
                                     ipmi_context_t context);

struct errno_cc_entry
{
    int err;
    int cc;
};

static const errno_cc_entry errno_cc_map[] = {
    {0, IPMI_CC_OK},
    {EBUSY, IPMI_CC_BUSY},
    {ENOTSUP, IPMI_CC_INVALID},
    {ETIMEDOUT, 0xc3}, /* FIXME: Replace when defined in ipmid-api.h */
    {ENOSPC, 0xc4},    /* FIXME: Replace when defined in ipmid-api.h */
    {EINVAL, IPMI_CC_PARM_OUT_OF_RANGE},
    {ENODEV, IPMI_CC_SENSOR_INVALID},
    {EPERM, IPMI_CC_INSUFFICIENT_PRIVILEGE},
    {EACCES, IPMI_CC_INSUFFICIENT_PRIVILEGE},
    {-1, IPMI_CC_UNSPECIFIED_ERROR},
};

static int hiomap_xlate_errno(int err)
{
    const errno_cc_entry *entry = &errno_cc_map[0];

    while (!(entry->err == err || entry->err == -1))
    {
        entry++;
    }

    return entry->cc;
}

static void ipmi_hiomap_event_response(IpmiCmdData cmd, bool status)
{
    using namespace phosphor::logging;

    if (!status)
    {
        log<level::ERR>("Failed to deliver host command",
                        entry("SEL_COMMAND=%x:%x", cmd.first, cmd.second));
    }
}

static int hiomap_handle_property_update(struct hiomap *ctx,
                                         sdbusplus::message::message &msg)
{
    std::map<std::string, sdbusplus::message::variant<bool>> msgData;

    std::string iface;
    msg.read(iface, msgData);

    for (auto const &x : msgData)
    {
        if (!ctx->event_lookup.count(x.first))
        {
            /* Unsupported event? */
            continue;
        }

        uint8_t mask = ctx->event_lookup[x.first];
        auto value = sdbusplus::message::variant_ns::get<bool>(x.second);

        if (value)
        {
            ctx->bmc_events |= mask;
        }
        else
        {
            ctx->bmc_events &= ~mask;
        }
    }

    auto cmd = std::make_pair(IPMI_CMD_HIOMAP_EVENT, ctx->bmc_events);

    ipmid_send_cmd_to_host(std::make_tuple(cmd, ipmi_hiomap_event_response));

    return 0;
}

static bus::match::match hiomap_match_properties(struct hiomap *ctx)
{
    auto properties =
        bus::match::rules::propertiesChanged(HIOMAPD_OBJECT, HIOMAPD_IFACE_V2);

    bus::match::match match(
        *ctx->bus, properties,
        std::bind(hiomap_handle_property_update, ctx, std::placeholders::_1));

    return match;
}

static int hiomap_handle_signal_v2(struct hiomap *ctx, const char *name)
{
    ctx->bmc_events |= ctx->event_lookup[name];

    auto cmd = std::make_pair(IPMI_CMD_HIOMAP_EVENT, ctx->bmc_events);

    ipmid_send_cmd_to_host(std::make_tuple(cmd, ipmi_hiomap_event_response));

    return 0;
}

static bus::match::match hiomap_match_signal_v2(struct hiomap *ctx,
                                                const char *name)
{
    using namespace bus::match;

    auto signals = rules::type::signal() + rules::path(HIOMAPD_OBJECT) +
                   rules::interface(HIOMAPD_IFACE_V2) + rules::member(name);

    bus::match::match match(*ctx->bus, signals,
                            std::bind(hiomap_handle_signal_v2, ctx, name));

    return match;
}

static ipmi_ret_t hiomap_reset(ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
{
    struct hiomap *ctx = static_cast<struct hiomap *>(context);

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE, "Reset");
    try
    {
        ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError &e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_get_info(ipmi_request_t request,
                                  ipmi_response_t response,
                                  ipmi_data_len_t data_len,
                                  ipmi_context_t context)
{
    struct hiomap *ctx = static_cast<struct hiomap *>(context);

    if (*data_len < 1)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t *reqdata = (uint8_t *)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE, "GetInfo");
    m.append(reqdata[0]);

    try
    {
        auto reply = ctx->bus->call(m);

        uint8_t version;
        uint8_t blockSizeShift;
        uint16_t timeout;
        reply.read(version, blockSizeShift, timeout);

        uint8_t *respdata = (uint8_t *)response;

        /* FIXME: Assumes v2! */
        put(&respdata[0], version);
        put(&respdata[1], blockSizeShift);
        put(&respdata[2], htole16(timeout));

        *data_len = 4;
    }
    catch (const exception::SdBusError &e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_get_flash_info(ipmi_request_t request,
                                        ipmi_response_t response,
                                        ipmi_data_len_t data_len,
                                        ipmi_context_t context)
{
    struct hiomap *ctx = static_cast<struct hiomap *>(context);

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "GetFlashInfo");
    try
    {
        auto reply = ctx->bus->call(m);

        uint16_t flashSize, eraseSize;
        reply.read(flashSize, eraseSize);

        uint8_t *respdata = (uint8_t *)response;
        put(&respdata[0], htole16(flashSize));
        put(&respdata[2], htole16(eraseSize));

        *data_len = 4;
    }
    catch (const exception::SdBusError &e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static const hiomap_command hiomap_commands[] = {
    [0] = NULL, /* 0 is an invalid command ID */
    [1] = hiomap_reset,
    [2] = hiomap_get_info,
    [3] = hiomap_get_flash_info,
};

/* FIXME: Define this in the "right" place, wherever that is */
/* FIXME: Double evaluation */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

static ipmi_ret_t hiomap_dispatch(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                  ipmi_request_t request,
                                  ipmi_response_t response,
                                  ipmi_data_len_t data_len,
                                  ipmi_context_t context)
{
    struct hiomap *ctx = static_cast<struct hiomap *>(context);

    if (*data_len < 2)
    {
        *data_len = 0;
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t *ipmi_req = (uint8_t *)request;
    uint8_t *ipmi_resp = (uint8_t *)response;
    uint8_t hiomap_cmd = ipmi_req[0];

    if (hiomap_cmd == 0 || hiomap_cmd > ARRAY_SIZE(hiomap_commands) - 1)
    {
        *data_len = 0;
        return IPMI_CC_PARM_OUT_OF_RANGE;
    }
    uint8_t *flash_req = ipmi_req + 2;
    size_t flash_len = *data_len - 2;
    uint8_t *flash_resp = ipmi_resp + 2;

    ipmi_ret_t cc =
        hiomap_commands[hiomap_cmd](flash_req, flash_resp, &flash_len, context);
    if (cc != IPMI_CC_OK)
    {
        *data_len = 0;
        return cc;
    }

    /* Populate the response command and sequence */
    ipmi_resp[0] = hiomap_cmd;
    ipmi_resp[1] = ipmi_req[1];

    *data_len = flash_len + 2;

    return cc;
}
} // namespace flash
} // namespace openpower

static void register_openpower_hiomap_commands()
{
    using namespace openpower::flash;

    /* FIXME: Clean this up? Can we unregister? */
    struct hiomap *ctx = new hiomap();

    /* Initialise mapping from signal and property names to status bit */
    ctx->event_lookup["DaemonReady"] = BMC_EVENT_DAEMON_READY;
    ctx->event_lookup["FlashControlLost"] = BMC_EVENT_FLASH_CTRL_LOST;
    ctx->event_lookup["WindowReset"] = BMC_EVENT_WINDOW_RESET;
    ctx->event_lookup["ProtocolReset"] = BMC_EVENT_PROTOCOL_RESET;

    ctx->bus = new bus::bus(ipmid_get_sd_bus_connection());

    /* Initialise signal handling */

    /*
     * Can't use temporaries here because that causes SEGFAULTs due to slot
     * destruction (!?), so enjoy the weird wrapping.
     */
    ctx->properties =
        new bus::match::match(std::move(hiomap_match_properties(ctx)));
    ctx->bmc_reboot = new bus::match::match(
        std::move(hiomap_match_signal_v2(ctx, "ProtocolReset")));
    ctx->window_reset = new bus::match::match(
        std::move(hiomap_match_signal_v2(ctx, "WindowReset")));

    ipmi_register_callback(NETFUN_IBM_OEM, IPMI_CMD_HIOMAP, ctx,
                           openpower::flash::hiomap_dispatch, SYSTEM_INTERFACE);
}
