#include "ipmid.hpp"

#include "host-cmd-manager.hpp"
#include "ipmiwhitelist.hpp"
#include "sensorhandler.hpp"
#include "settings.hpp"
#include "timer.hpp"

#include <assert.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <mapper.h>
#include <sys/time.h>
#include <systemd/sd-bus.h>
#include <unistd.h>

#include <algorithm>
#include <cstring>
#include <host-ipmid/ipmid-host-cmd.hpp>
#include <host-ipmid/oemrouter.hpp>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <vector>
#include <xyz/openbmc_project/Control/Security/RestrictionMode/server.hpp>

using namespace phosphor::logging;
namespace sdbusRule = sdbusplus::bus::match::rules;

sd_bus* bus = NULL;
sd_bus_slot* ipmid_slot = NULL;
sd_event* events = nullptr;

// Need this to use new sdbusplus compatible interfaces
sdbusPtr sdbusp;

// Global Host Bound Command manager
using cmdManagerPtr = std::unique_ptr<phosphor::host::command::Manager>;
cmdManagerPtr cmdManager;

// Global timer for network changes
std::unique_ptr<phosphor::ipmi::Timer> networkTimer = nullptr;

// Command and handler tuple. Used when clients ask the command to be put
// into host message queue
using CommandHandler = phosphor::host::command::CommandHandler;

// Initialise restricted mode to true
bool restricted_mode = true;

FILE *ipmiio, *ipmidbus, *ipmicmddetails;

void print_usage(void)
{
    std::fprintf(stderr, "Options:  [-d mask]\n");
    std::fprintf(stderr, "    mask : 0x01 - Print ipmi packets\n");
    std::fprintf(stderr, "    mask : 0x02 - Print DBUS operations\n");
    std::fprintf(stderr, "    mask : 0x04 - Print ipmi command details\n");
    std::fprintf(stderr, "    mask : 0xFF - Print all trace\n");
}

const char* DBUS_INTF = "org.openbmc.HostIpmi";

const char* FILTER =
    "type='signal',interface='org.openbmc.HostIpmi',member='ReceivedMessage'";

typedef std::pair<ipmi_netfn_t, ipmi_cmd_t> ipmi_fn_cmd_t;
typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;

// Global data structure that contains the IPMI command handler's registrations.
std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;

// IPMI Spec, shared Reservation ID.
unsigned short g_sel_reserve = 0xFFFF;

unsigned short get_sel_reserve_id(void)
{
    return g_sel_reserve;
}

namespace internal
{

constexpr auto restrictionModeIntf =
    "xyz.openbmc_project.Control.Security.RestrictionMode";

namespace cache
{

std::unique_ptr<settings::Objects> objects = nullptr;

} // namespace cache
} // namespace internal

#ifndef HEXDUMP_COLS
#define HEXDUMP_COLS 16
#endif

void hexdump(FILE* s, void* mem, size_t len)
{
    unsigned int i, j;

    for (i = 0;
         i <
         len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0);
         i++)
    {
        /* print offset */
        if (i % HEXDUMP_COLS == 0)
        {
            std::fprintf(s, "0x%06x: ", i);
        }

        /* print hex data */
        if (i < len)
        {
            std::fprintf(s, "%02x ", 0xFF & ((char*)mem)[i]);
        }
        else /* end of block, just aligning for ASCII dump */
        {
            std::fprintf(s, "   ");
        }

        /* print ASCII dump */
        if (i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
        {
            for (j = i - (HEXDUMP_COLS - 1); j <= i; j++)
            {
                if (j >= len) /* end of block, not really printing */
                {
                    std::fputc(' ', s);
                }
                else if (std::isprint(((char*)mem)[j])) /* printable char */
                {
                    std::fputc(0xFF & ((char*)mem)[j], s);
                }
                else /* other char */
                {
                    std::fputc('.', s);
                }
            }
            std::fputc('\n', s);
        }
    }
}

// Method that gets called by shared libraries to get their command handlers
// registered
void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                            ipmi_context_t context, ipmid_callback_t handler,
                            ipmi_cmd_privilege_t priv)
{
    // Pack NetFn and Command in one.
    auto netfn_and_cmd = std::make_pair(netfn, cmd);

    // Pack Function handler and Data in another.
    auto handler_and_context = std::make_pair(handler, context);

    // Check if the registration has already been made..
    auto iter = g_ipmid_router_map.find(netfn_and_cmd);
    if (iter != g_ipmid_router_map.end())
    {
        log<level::ERR>("Duplicate registration", entry("NETFN=0x%X", netfn),
                        entry("CMD=0x%X", cmd));
    }
    else
    {
        // This is a fresh registration.. Add it to the map.
        g_ipmid_router_map.emplace(netfn_and_cmd, handler_and_context);
    }

    return;
}

// Looks at the map and calls corresponding handler functions.
ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                             ipmi_request_t request, ipmi_response_t response,
                             ipmi_data_len_t data_len)
{
    // return from the Command handlers.
    ipmi_ret_t rc = IPMI_CC_INVALID;

    // If restricted mode is true and command is not whitelisted, don't
    // execute the command
    if (restricted_mode)
    {
        if (!std::binary_search(whitelist.cbegin(), whitelist.cend(),
                                std::make_pair(netfn, cmd)))
        {
            log<level::ERR>("Net function not whitelisted",
                            entry("NETFN=0x%X", netfn), entry("CMD=0x%X", cmd));
            rc = IPMI_CC_INSUFFICIENT_PRIVILEGE;
            std::memcpy(response, &rc, IPMI_CC_LEN);
            *data_len = IPMI_CC_LEN;
            return rc;
        }
    }

    // Walk the map that has the registered handlers and invoke the approprite
    // handlers for matching commands.
    auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd));
    if (iter == g_ipmid_router_map.end())
    {
        /* By default should only print on failure to find wildcard command. */
#ifdef __IPMI_DEBUG__
        log<level::ERR>(
            "No registered handlers for NetFn, trying Wilcard implementation",
            entry("NET_FUN=0x%X", netfn) entry("CMD=0x%X", IPMI_CMD_WILDCARD));
#endif

        // Now that we did not find any specific [NetFn,Cmd], tuple, check for
        // NetFn, WildCard command present.
        iter =
            g_ipmid_router_map.find(std::make_pair(netfn, IPMI_CMD_WILDCARD));
        if (iter == g_ipmid_router_map.end())
        {
            log<level::ERR>("No Registered handlers for NetFn",
                            entry("NET_FUN=0x%X", netfn),
                            entry("CMD=0x%X", IPMI_CMD_WILDCARD));

            // Respond with a 0xC1
            std::memcpy(response, &rc, IPMI_CC_LEN);
            *data_len = IPMI_CC_LEN;
            return rc;
        }
    }

#ifdef __IPMI_DEBUG__
    // We have either a perfect match -OR- a wild card atleast,
    log<level::ERR>("Calling Net function",
                    entry("NET_FUN=0x%X", netfn) entry("CMD=0x%X", cmd));
#endif

    // Extract the map data onto appropriate containers
    auto handler_and_context = iter->second;

    // Creating a pointer type casted to char* to make sure we advance 1 byte
    // when we advance pointer to next's address. advancing void * would not
    // make sense.
    char* respo = &((char*)response)[IPMI_CC_LEN];

    try
    {
        // Response message from the plugin goes into a byte post the base
        // response
        rc = (handler_and_context.first)(netfn, cmd, request, respo, data_len,
                                         handler_and_context.second);
    }
    // IPMI command handlers can throw unhandled exceptions, catch those
    // and return sane error code.
    catch (const std::exception& e)
    {
        log<level::ERR>(e.what(), entry("NET_FUN=0x%X", netfn),
                        entry("CMD=0x%X", cmd));
        rc = IPMI_CC_UNSPECIFIED_ERROR;
        *data_len = 0;
        // fall through
    }
    // Now copy the return code that we got from handler and pack it in first
    // byte.
    std::memcpy(response, &rc, IPMI_CC_LEN);

    // Data length is now actual data + completion code.
    *data_len = *data_len + IPMI_CC_LEN;

    return rc;
}

static int send_ipmi_message(sd_bus_message* req, unsigned char seq,
                             unsigned char netfn, unsigned char lun,
                             unsigned char cmd, unsigned char cc,
                             unsigned char* buf, unsigned char len)
{

    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *reply = NULL, *m = NULL;
    const char *dest, *path;
    int r, pty;

    dest = sd_bus_message_get_sender(req);
    path = sd_bus_message_get_path(req);

    r = sd_bus_message_new_method_call(bus, &m, dest, path, DBUS_INTF,
                                       "sendMessage");
    if (r < 0)
    {
        log<level::ERR>("Failed to add the method object",
                        entry("ERRNO=0x%X", -r));
        return -1;
    }

    // Responses in IPMI require a bit set.  So there ya go...
    netfn |= 0x01;

    // Add the bytes needed for the methods to be called
    r = sd_bus_message_append(m, "yyyyy", seq, netfn, lun, cmd, cc);
    if (r < 0)
    {
        log<level::ERR>("Failed add the netfn and others",
                        entry("ERRNO=0x%X", -r));
        goto final;
    }

    r = sd_bus_message_append_array(m, 'y', buf, len);
    if (r < 0)
    {
        log<level::ERR>("Failed to add the string of response bytes",
                        entry("ERRNO=0x%X", -r));
        goto final;
    }

    // Call the IPMI responder on the bus so the message can be sent to the CEC
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0)
    {
        log<level::ERR>("Failed to call the method", entry("DEST=%s", dest),
                        entry("PATH=%s", path), entry("ERRNO=0x%X", -r));
        goto final;
    }

    r = sd_bus_message_read(reply, "x", &pty);
    if (r < 0)
    {
        log<level::ERR>("Failed to get a reply from the method",
                        entry("ERRNO=0x%X", -r));
    }

final:
    sd_bus_error_free(&error);
    m = sd_bus_message_unref(m);
    reply = sd_bus_message_unref(reply);

    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

void cache_restricted_mode()
{
    restricted_mode = false;
    using namespace sdbusplus::xyz::openbmc_project::Control::Security::server;
    using namespace internal;
    using namespace internal::cache;
    sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
    const auto& restrictionModeSetting =
        objects->map.at(restrictionModeIntf).front();
    auto method = dbus.new_method_call(
        objects->service(restrictionModeSetting, restrictionModeIntf).c_str(),
        restrictionModeSetting.c_str(), "org.freedesktop.DBus.Properties",
        "Get");
    method.append(restrictionModeIntf, "RestrictionMode");
    auto resp = dbus.call(method);
    if (resp.is_method_error())
    {
        log<level::ERR>("Error in RestrictionMode Get");
        // Fail-safe to true.
        restricted_mode = true;
        return;
    }
    sdbusplus::message::variant<std::string> result;
    resp.read(result);
    auto restrictionMode =
        RestrictionMode::convertModesFromString(result.get<std::string>());
    if (RestrictionMode::Modes::Whitelist == restrictionMode)
    {
        restricted_mode = true;
    }
}

static int handle_restricted_mode_change(sd_bus_message* m, void* user_data,
                                         sd_bus_error* ret_error)
{
    cache_restricted_mode();
    return 0;
}

static int handle_ipmi_command(sd_bus_message* m, void* user_data,
                               sd_bus_error* ret_error)
{
    int r = 0;
    unsigned char sequence, netfn, lun, cmd;
    const void* request;
    size_t sz;
    size_t resplen = MAX_IPMI_BUFFER;
    unsigned char response[MAX_IPMI_BUFFER];

    std::memset(response, 0, MAX_IPMI_BUFFER);

    r = sd_bus_message_read(m, "yyyy", &sequence, &netfn, &lun, &cmd);
    if (r < 0)
    {
        log<level::ERR>("Failed to parse signal message",
                        entry("ERRNO=0x%X", -r));
        return -1;
    }

    r = sd_bus_message_read_array(m, 'y', &request, &sz);
    if (r < 0)
    {
        log<level::ERR>("Failed to parse signal message",
                        entry("ERRNO=0x%X", -r));
        return -1;
    }

    std::fprintf(ipmiio,
                 "IPMI Incoming: Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n",
                 sequence, netfn, cmd);
    hexdump(ipmiio, (void*)request, sz);

    // Allow the length field to be used for both input and output of the
    // ipmi call
    resplen = sz;

    // Now that we have parsed the entire byte array from the caller
    // we can call the ipmi router to do the work...
    r = ipmi_netfn_router(netfn, cmd, (void*)request, (void*)response,
                          &resplen);
    if (r != 0)
    {
#ifdef __IPMI_DEBUG__
        log<level::ERR>("ERROR in handling NetFn", entry("ERRNO=0x%X", -r),
                        entry("NET_FUN=0x%X", netfn), entry("CMD=0x%X", cmd));
#endif
        resplen = 0;
    }
    else
    {
        resplen = resplen - 1; // first byte is for return code.
    }

    std::fprintf(ipmiio, "IPMI Response:\n");
    hexdump(ipmiio, (void*)response, resplen);

    // Send the response buffer from the ipmi command
    r = send_ipmi_message(m, sequence, netfn, lun, cmd, response[0],
                          ((unsigned char*)response) + 1, resplen);
    if (r < 0)
    {
        log<level::ERR>("Failed to send the response message");
        return -1;
    }

    return 0;
}

//----------------------------------------------------------------------
// handler_select
// Select all the files ending with with .so. in the given diretcory
// @d: dirent structure containing the file name
//----------------------------------------------------------------------
int handler_select(const struct dirent* entry)
{
    // To hold ".so" from entry->d_name;
    char dname_copy[4] = {0};

    // We want to avoid checking for everything and isolate to the ones having
    // .so.* or .so in them.
    // Check for versioned libraries .so.*
    if (strstr(entry->d_name, IPMI_PLUGIN_SONAME_EXTN))
    {
        return 1;
    }
    // Check for non versioned libraries .so
    else if (strstr(entry->d_name, IPMI_PLUGIN_EXTN))
    {
        // It is possible that .so could be anywhere in the string but unlikely
        // But being careful here. Get the base address of the string, move
        // until end and come back 3 steps and that gets what we need.
        strcpy(dname_copy, (entry->d_name + strlen(entry->d_name) -
                            strlen(IPMI_PLUGIN_EXTN)));
        if (strcmp(dname_copy, IPMI_PLUGIN_EXTN) == 0)
        {
            return 1;
        }
    }
    return 0;
}

// This will do a dlopen of every .so in ipmi_lib_path and will dlopen
// everything so that they will register a callback handler
void ipmi_register_callback_handlers(const char* ipmi_lib_path)
{
    // For walking the ipmi_lib_path
    struct dirent** handler_list;
    int num_handlers = 0;

    // This is used to check and abort if someone tries to register a bad one.
    void* lib_handler = NULL;

    if (ipmi_lib_path == NULL)
    {
        log<level::ERR>("No handlers to be registered for ipmi.. Aborting");
        assert(0);
    }
    else
    {
        // 1: Open ipmi_lib_path. Its usually "/usr/lib/phosphor-host-ipmid"
        // 2: Scan the directory for the files that end with .so
        // 3: For each one of them, just do a 'dlopen' so that they register
        //    the handlers for callback routines.

        std::string handler_fqdn = ipmi_lib_path;

        // Append a "/" since we need to add the name of the .so. If there is
        // already a .so, adding one more is not any harm.
        handler_fqdn += "/";

        num_handlers =
            scandir(ipmi_lib_path, &handler_list, handler_select, alphasort);
        if (num_handlers < 0)
            return;

        while (num_handlers--)
        {
            handler_fqdn = ipmi_lib_path;
            handler_fqdn += handler_list[num_handlers]->d_name;
#ifdef __IPMI_DEBUG__
            log<level::DEBUG>("Registering handler",
                              entry("HANDLER=%s", handler_fqdn.c_str()));
#endif

            lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);

            if (lib_handler == NULL)
            {
                log<level::ERR>("ERROR opening",
                                entry("HANDLER=%s", handler_fqdn.c_str()),
                                entry("ERROR=%s", dlerror()));
            }
            // Wipe the memory allocated for this particular entry.
            free(handler_list[num_handlers]);
        }

        // Done with all registration.
        free(handler_list);
    }

    // TODO : What to be done on the memory that is given by dlopen ?.
    return;
}

sd_bus* ipmid_get_sd_bus_connection(void)
{
    return bus;
}

sd_event* ipmid_get_sd_event_connection(void)
{
    return events;
}

sd_bus_slot* ipmid_get_sd_bus_slot(void)
{
    return ipmid_slot;
}

// Calls host command manager to do the right thing for the command
void ipmid_send_cmd_to_host(CommandHandler&& cmd)
{
    return cmdManager->execute(std::move(cmd));
}

cmdManagerPtr& ipmid_get_host_cmd_manager()
{
    return cmdManager;
}

sdbusPtr& ipmid_get_sdbus_plus_handler()
{
    return sdbusp;
}

int main(int argc, char* argv[])
{
    int r;
    unsigned long tvalue;
    int c;

    // This file and subsequient switch is for turning on levels
    // of trace
    ipmicmddetails = ipmiio = ipmidbus = fopen("/dev/null", "w");

    while ((c = getopt(argc, argv, "h:d:")) != -1)
        switch (c)
        {
            case 'd':
                tvalue = strtoul(optarg, NULL, 16);
                if (1 & tvalue)
                {
                    ipmiio = stdout;
                }
                if (2 & tvalue)
                {
                    ipmidbus = stdout;
                }
                if (4 & tvalue)
                {
                    ipmicmddetails = stdout;
                }
                break;
            case 'h':
            case '?':
                print_usage();
                return 1;
        }

    /* Connect to system bus */
    r = sd_bus_open_system(&bus);
    if (r < 0)
    {
        log<level::ERR>("Failed to connect to system bus",
                        entry("ERRNO=0x%X", -r));
        goto finish;
    }

    /* Get an sd event handler */
    r = sd_event_default(&events);
    if (r < 0)
    {
        log<level::ERR>("Failure to create sd_event handler",
                        entry("ERRNO=0x%X", -r));
        goto finish;
    }

    // Now create the Host Bound Command manager. Need sdbusplus
    // to use the generated bindings
    sdbusp = std::make_unique<sdbusplus::bus::bus>(bus);
    cmdManager =
        std::make_unique<phosphor::host::command::Manager>(*sdbusp, events);

    // Activate OemRouter.
    oem::mutableRouter()->activate();

    // Register all the handlers that provider implementation to IPMI commands.
    ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);

    // Watch for BT messages
    r = sd_bus_add_match(bus, &ipmid_slot, FILTER, handle_ipmi_command, NULL);
    if (r < 0)
    {
        log<level::ERR>("Failed: sd_bus_add_match", entry("FILTER=%s", FILTER),
                        entry("ERRNO=0x%X", -r));
        goto finish;
    }

    // Attach the bus to sd_event to service user requests
    sd_bus_attach_event(bus, events, SD_EVENT_PRIORITY_NORMAL);

    {
        using namespace internal;
        using namespace internal::cache;
        sdbusplus::bus::bus dbus{bus};
        objects = std::make_unique<settings::Objects>(
            dbus, std::vector<settings::Interface>({restrictionModeIntf}));
        // Initialize restricted mode
        cache_restricted_mode();
        // Wait for changes on Restricted mode
        sdbusplus::bus::match_t restrictedModeMatch(
            dbus,
            sdbusRule::propertiesChanged(
                objects->map.at(restrictionModeIntf).front(),
                restrictionModeIntf),
            handle_restricted_mode_change);

        for (;;)
        {
            /* Process requests */
            r = sd_event_run(events, (uint64_t)-1);
            if (r < 0)
            {
                log<level::ERR>("Failure in processing request",
                                entry("ERRNO=0x%X", -r));
                goto finish;
            }
        }
    }

finish:
    sd_event_unref(events);
    sd_bus_detach_event(bus);
    sd_bus_slot_unref(ipmid_slot);
    sd_bus_unref(bus);
    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
