#include <stdio.h>
#include <dlfcn.h>
#include <iostream>
#include <unistd.h>
#include <assert.h>
#include <dirent.h>
#include <systemd/sd-bus.h>
#include <string.h>
#include <stdlib.h>
#include <map>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <sys/time.h>
#include <errno.h>
#include <mapper.h>
#include "sensorhandler.h"
#include <vector>
#include <algorithm>
#include <iterator>
#include <ipmiwhitelist.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <xyz/openbmc_project/Control/Security/RestrictionMode/server.hpp>
#include "sensorhandler.h"
#include "ipmid.hpp"
#include "settings.hpp"
#include <host-cmd-manager.hpp>
#include <host-ipmid/ipmid-host-cmd.hpp>
#include <timer.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) {
  fprintf(stderr, "Options:  [-d mask]\n");
  fprintf(stderr, "    mask : 0x01 - Print ipmi packets\n");
  fprintf(stderr, "    mask : 0x02 - Print DBUS operations\n");
  fprintf(stderr, "    mask : 0x04 - Print ipmi command details\n");
  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)
                {
                        fprintf(s,"0x%06x: ", i);
                }

                /* print hex data */
                if(i < len)
                {
                        fprintf(s,"%02x ", 0xFF & ((char*)mem)[i]);
                }
                else /* end of block, just aligning for ASCII dump */
                {
                        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 */
                                {
                                        fputc(' ', s);
                                }
                                else if(isprint(((char*)mem)[j])) /* printable char */
                                {
                                        fputc(0xFF & ((char*)mem)[j], s);
                                }
                                else /* other char */
                                {
                                        fputc('.',s);
                                }
                        }
                        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())
    {
        fprintf(stderr,"ERROR : Duplicate registration for NetFn [0x%X], Cmd:[0x%X]\n",netfn, 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)))
        {
            printf("Net function:[0x%X], Command:[0x%X] is not whitelisted\n",
                                         netfn, cmd);
            rc = IPMI_CC_INSUFFICIENT_PRIVILEGE;
            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__
        fprintf(stderr, "No registered handlers for NetFn:[0x%X], Cmd:[0x%X]"
               " trying Wilcard implementation \n",netfn, cmd);
#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())
        {
            fprintf(stderr, "No Registered handlers for NetFn:[0x%X],Cmd:[0x%X]\n",netfn, IPMI_CMD_WILDCARD);

            // Respond with a 0xC1
            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,
    printf("Calling Net function:[0x%X], Command:[0x%X]\n", netfn, 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];

    // 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);

    // Now copy the return code that we got from handler and pack it in first
    // byte.
    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) {
        fprintf(stderr, "Failed to add the method object: %s\n", strerror(-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) {
        fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
        goto final;
    }

    r = sd_bus_message_append_array(m, 'y', buf, len);
    if (r < 0) {
        fprintf(stderr, "Failed to add the string of response bytes: %s\n", strerror(-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) {
        fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
        fprintf(stderr, "Dest: %s, Path: %s\n", dest, path);
        goto final;
    }

    r = sd_bus_message_read(reply, "x", &pty);
    if (r < 0) {
       fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-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];

    memset(response, 0, MAX_IPMI_BUFFER);

    r = sd_bus_message_read(m, "yyyy",  &sequence, &netfn, &lun, &cmd);
    if (r < 0) {
        fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
        return -1;
    }

    r = sd_bus_message_read_array(m, 'y',  &request, &sz );
    if (r < 0) {
        fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
        return -1;
    }

    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)
    {
        fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",r, netfn, cmd);
        resplen = 0;
    }
    else
    {
        resplen = resplen - 1; // first byte is for return code.
    }

    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) {
        fprintf(stderr, "Failed to send the response message\n");
        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)
    {
        fprintf(stderr,"ERROR; No handlers to be registered for ipmi.. Aborting\n");
        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;
            printf("Registering handler:[%s]\n",handler_fqdn.c_str());

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

            if(lib_handler == NULL)
            {
                fprintf(stderr,"ERROR opening [%s]: %s\n",
                        handler_fqdn.c_str(), 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) {
        fprintf(stderr, "Failed to connect to system bus: %s\n",
                strerror(-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("ERROR=%s", strerror(-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);

    // 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) {
        fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);
        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("ERROR=%s", strerror(-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;

}
