#include <stdint.h>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <memory>
#include <systemd/sd-bus.h>
#include <mapper.h>
#include <phosphor-logging/elog.hpp>
#include "host-ipmid/ipmid-api.h"
#include "elog-errors.hpp"
#include "error-HostEvent.hpp"
#include "sensorhandler.h"
#include "storagehandler.h"
#include "types.hpp"
#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)));
}
