#include "elog-errors.hpp"
#include "error-HostEvent.hpp"
#include "sensorhandler.hpp"
#include "storagehandler.hpp"
#include "types.hpp"

#include <host-ipmid/ipmid-api.h>
#include <mapper.h>
#include <stdint.h>
#include <systemd/sd-bus.h>

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <memory>
#include <phosphor-logging/elog.hpp>
#include <vector>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>

using namespace std;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Logging::server;
extern const ipmi::sensor::InvObjectIDMap invSensors;

//////////////////////////
struct esel_section_headers_t
{
    uint8_t sectionid[2];
    uint8_t sectionlength[2];
    uint8_t version;
    uint8_t subsectiontype;
    uint8_t compid;
};

struct severity_values_t
{
    uint8_t type;
    Entry::Level level;
};

const std::vector<severity_values_t> g_sev_desc = {
    {0x10, Entry::Level::Warning}, // recoverable error
    {0x20, Entry::Level::Warning}, // predictive error
                                   // TODO via github issue 3066 : map level
                                   // below to Level::Unrecoverable
    {0x40, Entry::Level::Error},   // unrecoverable error
                                 // TODO via github issue 3066 : map level below
                                 // to Level::Critical
    {0x50, Entry::Level::Error},   // critical error
    {0x60, Entry::Level::Error},   // error from a diagnostic test
    {0x70, Entry::Level::Warning}, // recoverable symptom
    {0xFF, Entry::Level::Error},   // unknown error
};

Entry::Level sev_lookup(uint8_t n)
{
    auto i =
        std::find_if(std::begin(g_sev_desc), std::end(g_sev_desc),
                     [n](auto p) { return p.type == n || p.type == 0xFF; });
    return i->level;
}

int find_sensor_type_string(uint8_t sensor_number, char** s)
{

    dbus_interface_t a;
    const char* p;
    int r;

    r = find_openbmc_path(sensor_number, &a);

    if ((r < 0) || (a.bus[0] == 0))
    {
        // Just make a generic message for errors that
        // occur on sensors that don't exist
        r = asprintf(s, "Unknown Sensor (0x%02x)", sensor_number);
    }
    else
    {

        if ((p = strrchr(a.path, '/')) == NULL)
        {
            p = "/Unknown Sensor";
        }

        *s = strdup(p + 1);
    }

    return 0;
}

size_t getfilestream(const char* fn, uint8_t** buffer)
{

    FILE* fp;
    ssize_t size = 0;
    int r;

    if ((fp = fopen(fn, "rb")) != NULL)
    {

        r = fseek(fp, 0, SEEK_END);
        if (r)
        {
            log<level::ERR>("Fseek failed");
            goto fclose_fp;
        }

        size = ftell(fp);
        if (size == -1L)
        {
            log<level::ERR>("Ftell failed", entry("ERROR=%s", strerror(errno)));
            size = 0;
            goto fclose_fp;
        }

        r = fseek(fp, 0, SEEK_SET);
        if (r)
        {
            log<level::ERR>("Fseek failed");
            size = 0;
            goto fclose_fp;
        }

        *buffer = new uint8_t[size];

        r = fread(*buffer, 1, size, fp);
        if (r != size)
        {
            size = 0;
            log<level::ERR>("Fread failed\n");
        }

    fclose_fp:
        fclose(fp);
    }

    return static_cast<size_t>(size);
}

Entry::Level create_esel_severity(const uint8_t* buffer)
{

    uint8_t severity;
    // Dive in to the IBM log to find the severity
    severity = (0xF0 & buffer[0x4A]);

    return sev_lookup(severity);
}

int create_esel_association(const uint8_t* buffer, std::string& inventoryPath)
{
    ipmi_add_sel_request_t* p;
    uint8_t sensor;

    p = (ipmi_add_sel_request_t*)buffer;

    sensor = p->sensornumber;

    inventoryPath = {};

    /*
     * Search the sensor number to inventory path mapping to figure out the
     * inventory associated with the ESEL.
     */
    for (auto const& iter : invSensors)
    {
        if (iter.second.sensorID == sensor)
        {
            inventoryPath = iter.first;
            break;
        }
    }

    return 0;
}

int create_esel_description(const uint8_t* buffer, Entry::Level level,
                            char** message)
{

    ipmi_add_sel_request_t* p;
    char* m;
    int r;

    p = (ipmi_add_sel_request_t*)buffer;

    find_sensor_type_string(p->sensornumber, &m);

    r = asprintf(message, "A %s has experienced an error of level %d", m,
                 static_cast<uint32_t>(level));
    if (r == -1)
    {
        log<level::ERR>("Failed to allocate memory for ESEL description");
    }

    free(m);

    return 0;
}

int send_esel_to_dbus(const char* desc, Entry::Level level,
                      const std::string& inventoryPath, uint8_t* debug,
                      size_t debuglen)
{

    // Allocate enough space to represent the data in hex separated by spaces,
    // to mimic how IPMI would display the data.
    unique_ptr<char[]> selData(new char[(debuglen * 3) + 1]());
    uint32_t i = 0;
    for (i = 0; i < debuglen; i++)
    {
        sprintf(&selData[i * 3], "%02x ", 0xFF & ((char*)debug)[i]);
    }
    selData[debuglen * 3] = '\0';

    using error = sdbusplus::org::open_power::Host::Error::Event;
    using metadata = org::open_power::Host::Event;

    report<error>(level, metadata::ESEL(selData.get()),
                  metadata::CALLOUT_INVENTORY_PATH(inventoryPath.c_str()));

    return 0;
}

void send_esel(uint16_t recordid)
{
    char* desc;
    uint8_t* buffer = NULL;
    const char* path = "/tmp/esel";
    ssize_t sz;
    int r;
    std::string inventoryPath;

    sz = getfilestream(path, &buffer);
    if (sz == 0)
    {
        log<level::ERR>("Error file does not exist",
                        entry("FILENAME=%s", path));
        return;
    }

    auto sev = create_esel_severity(buffer);
    create_esel_association(buffer, inventoryPath);
    create_esel_description(buffer, sev, &desc);

    r = send_esel_to_dbus(desc, sev, inventoryPath, buffer, sz);
    if (r < 0)
    {
        log<level::ERR>("Failed to send esel to dbus");
    }

    free(desc);
    delete[] buffer;

    return;
}

std::string readESEL(const char* fileName)
{
    std::string content;
    std::ifstream handle(fileName);

    if (handle.fail())
    {
        log<level::ERR>("Failed to open eSEL", entry("FILENAME=%s", fileName));
        return content;
    }

    handle.seekg(0, std::ios::end);
    content.resize(handle.tellg());
    handle.seekg(0, std::ios::beg);
    handle.read(&content[0], content.size());
    handle.close();

    return content;
}

void createProcedureLogEntry(uint8_t procedureNum)
{
    // Read the eSEL data from the file.
    static constexpr auto eSELFile = "/tmp/esel";
    auto eSELData = readESEL(eSELFile);

    // Each byte in eSEL is formatted as %02x with a space between bytes and
    // insert '/0' at the end of the character array.
    static constexpr auto byteSeparator = 3;
    std::unique_ptr<char[]> data(
        new char[(eSELData.size() * byteSeparator) + 1]());

    for (size_t i = 0; i < eSELData.size(); i++)
    {
        sprintf(&data[i * byteSeparator], "%02x ", eSELData[i]);
    }
    data[eSELData.size() * byteSeparator] = '\0';

    using error = sdbusplus::org::open_power::Host::Error::MaintenanceProcedure;
    using metadata = org::open_power::Host::MaintenanceProcedure;

    report<error>(metadata::ESEL(data.get()),
                  metadata::PROCEDURE(static_cast<uint32_t>(procedureNum)));
}
