#pragma once

#include "types.hpp"

#include <host-ipmid/ipmid-api.h>
#include <stdint.h>

// IPMI commands for net functions.
enum ipmi_netfn_sen_cmds
{
    IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
    IPMI_CMD_GET_DEVICE_SDR = 0x21,
    IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
    IPMI_CMD_GET_SENSOR_READING = 0x2D,
    IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
    IPMI_CMD_SET_SENSOR = 0x30,
    IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
};

/**
 * @enum device_type
 * IPMI FRU device types
 */
enum device_type
{
    IPMI_PHYSICAL_FRU = 0x00,
    IPMI_LOGICAL_FRU = 0x80,
};

// Discrete sensor types.
enum ipmi_sensor_types
{
    IPMI_SENSOR_TEMP = 0x01,
    IPMI_SENSOR_VOLTAGE = 0x02,
    IPMI_SENSOR_CURRENT = 0x03,
    IPMI_SENSOR_FAN = 0x04,
    IPMI_SENSOR_TPM = 0xCC,
};

#define MAX_DBUS_PATH 128
struct dbus_interface_t
{
    uint8_t sensornumber;
    uint8_t sensortype;

    char bus[MAX_DBUS_PATH];
    char path[MAX_DBUS_PATH];
    char interface[MAX_DBUS_PATH];
};

int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
int find_openbmc_path(uint8_t, dbus_interface_t*);

ipmi_ret_t ipmi_sen_get_sdr(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);

ipmi_ret_t ipmi_sen_reserve_sdr(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);

static const uint16_t FRU_RECORD_ID_START = 256;
static const uint8_t SDR_VERSION = 0x51;
static const uint16_t END_OF_RECORD = 0xFFFF;
static const uint8_t LENGTH_MASK = 0x1F;

/**
 * Get SDR Info
 */

namespace get_sdr_info
{
namespace request
{
// Note: for some reason the ipmi_request_t appears to be the
// raw value for this call.
inline bool get_count(void* req)
{
    return (bool)((uint64_t)(req)&1);
}
} // namespace request

namespace response
{
#define SDR_INFO_RESP_SIZE 2
inline void set_lun_present(int lun, uint8_t* resp)
{
    *resp |= 1 << lun;
}
inline void set_lun_not_present(int lun, uint8_t* resp)
{
    *resp &= ~(1 << lun);
}
inline void set_dynamic_population(uint8_t* resp)
{
    *resp |= 1 << 7;
}
inline void set_static_population(uint8_t* resp)
{
    *resp &= ~(1 << 7);
}
} // namespace response

struct GetSdrInfoResp
{
    uint8_t count;
    uint8_t luns_and_dynamic_population;
};

} // namespace get_sdr_info

/**
 * Get SDR
 */
namespace get_sdr
{

struct GetSdrReq
{
    uint8_t reservation_id_lsb;
    uint8_t reservation_id_msb;
    uint8_t record_id_lsb;
    uint8_t record_id_msb;
    uint8_t offset;
    uint8_t bytes_to_read;
} __attribute__((packed));

namespace request
{

inline uint8_t get_reservation_id(GetSdrReq* req)
{
    return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
};

inline uint16_t get_record_id(GetSdrReq* req)
{
    return (req->record_id_lsb + (req->record_id_msb << 8));
};

} // namespace request

// Response
struct GetSdrResp
{
    uint8_t next_record_id_lsb;
    uint8_t next_record_id_msb;
    uint8_t record_data[64];
} __attribute__((packed));

namespace response
{

inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
{
    resp->next_record_id_lsb = next & 0xff;
    resp->next_record_id_msb = (next >> 8) & 0xff;
};

} // namespace response

// Record header
struct SensorDataRecordHeader
{
    uint8_t record_id_lsb;
    uint8_t record_id_msb;
    uint8_t sdr_version;
    uint8_t record_type;
    uint8_t record_length; // Length not counting the header
} __attribute__((packed));

namespace header
{

inline void set_record_id(int id, SensorDataRecordHeader* hdr)
{
    hdr->record_id_lsb = (id & 0xFF);
    hdr->record_id_msb = (id >> 8) & 0xFF;
};

} // namespace header

enum SensorDataRecordType
{
    SENSOR_DATA_FULL_RECORD = 0x1,
    SENSOR_DATA_FRU_RECORD = 0x11,
};

// Record key
struct SensorDataRecordKey
{
    uint8_t owner_id;
    uint8_t owner_lun;
    uint8_t sensor_number;
} __attribute__((packed));

/** @struct SensorDataFruRecordKey
 *
 *  FRU Device Locator Record(key) - SDR Type 11
 */
struct SensorDataFruRecordKey
{
    uint8_t deviceAddress;
    uint8_t fruID;
    uint8_t accessLun;
    uint8_t channelNumber;
} __attribute__((packed));

namespace key
{

inline void set_owner_id_ipmb(SensorDataRecordKey* key)
{
    key->owner_id &= ~0x01;
};

inline void set_owner_id_system_sw(SensorDataRecordKey* key)
{
    key->owner_id |= 0x01;
};

inline void set_owner_id_bmc(SensorDataRecordKey* key)
{
    key->owner_id |= 0x20;
};

inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
{
    key->owner_id &= 0x01;
    key->owner_id |= addr << 1;
};

inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
{
    key->owner_lun &= ~0x03;
    key->owner_lun |= (lun & 0x03);
};

inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
{
    key->owner_lun &= 0x0f;
    key->owner_lun |= ((channel & 0xf) << 4);
};

} // namespace key

/** @struct GetSensorThresholdsResponse
 *
 *  Response structure for Get Sensor Thresholds command
 */
struct GetSensorThresholdsResponse
{
    uint8_t validMask;           //!< valid mask
    uint8_t lowerNonCritical;    //!< lower non-critical threshold
    uint8_t lowerCritical;       //!< lower critical threshold
    uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
    uint8_t upperNonCritical;    //!< upper non-critical threshold
    uint8_t upperCritical;       //!< upper critical threshold
    uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
} __attribute__((packed));

// Body - full record
#define FULL_RECORD_ID_STR_MAX_LENGTH 16

static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;

struct SensorDataFullRecordBody
{
    uint8_t entity_id;
    uint8_t entity_instance;
    uint8_t sensor_initialization;
    uint8_t sensor_capabilities; // no macro support
    uint8_t sensor_type;
    uint8_t event_reading_type;
    uint8_t supported_assertions[2];          // no macro support
    uint8_t supported_deassertions[2];        // no macro support
    uint8_t discrete_reading_setting_mask[2]; // no macro support
    uint8_t sensor_units_1;
    uint8_t sensor_units_2_base;
    uint8_t sensor_units_3_modifier;
    uint8_t linearization;
    uint8_t m_lsb;
    uint8_t m_msb_and_tolerance;
    uint8_t b_lsb;
    uint8_t b_msb_and_accuracy_lsb;
    uint8_t accuracy_and_sensor_direction;
    uint8_t r_b_exponents;
    uint8_t analog_characteristic_flags; // no macro support
    uint8_t nominal_reading;
    uint8_t normal_max;
    uint8_t normal_min;
    uint8_t sensor_max;
    uint8_t sensor_min;
    uint8_t upper_nonrecoverable_threshold;
    uint8_t upper_critical_threshold;
    uint8_t upper_noncritical_threshold;
    uint8_t lower_nonrecoverable_threshold;
    uint8_t lower_critical_threshold;
    uint8_t lower_noncritical_threshold;
    uint8_t positive_threshold_hysteresis;
    uint8_t negative_threshold_hysteresis;
    uint16_t reserved;
    uint8_t oem_reserved;
    uint8_t id_string_info;
    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
} __attribute__((packed));

/** @struct SensorDataFruRecordBody
 *
 *  FRU Device Locator Record(body) - SDR Type 11
 */
struct SensorDataFruRecordBody
{
    uint8_t reserved;
    uint8_t deviceType;
    uint8_t deviceTypeModifier;
    uint8_t entityID;
    uint8_t entityInstance;
    uint8_t oem;
    uint8_t deviceIDLen;
    char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
} __attribute__((packed));

namespace body
{

inline void set_entity_instance_number(uint8_t n,
                                       SensorDataFullRecordBody* body)
{
    body->entity_instance &= 1 << 7;
    body->entity_instance |= (n & ~(1 << 7));
};
inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
{
    body->entity_instance &= ~(1 << 7);
};
inline void set_entity_logical_container(SensorDataFullRecordBody* body)
{
    body->entity_instance |= 1 << 7;
};

inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 0;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 0);
    };
};
inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 1;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 1);
    }
};
inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 2;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 2);
    }
};
inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 3;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 3);
    }
};
inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 4;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 4);
    }
};
inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 5;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 5);
    }
};
inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 6;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 6);
    }
};
inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
{
    if (enabled)
    {
        body->sensor_initialization |= 1 << 7;
    }
    else
    {
        body->sensor_initialization &= ~(1 << 7);
    }
};

inline void set_percentage(SensorDataFullRecordBody* body)
{
    body->sensor_units_1 |= 1 << 0;
};
inline void unset_percentage(SensorDataFullRecordBody* body)
{
    body->sensor_units_1 &= ~(1 << 0);
};
inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
{
    body->sensor_units_1 &= ~(3 << 1);
    body->sensor_units_1 |= (op & 0x3) << 1;
};
inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
{
    body->sensor_units_1 &= ~(7 << 3);
    body->sensor_units_1 |= (unit & 0x7) << 3;
};
inline void set_analog_data_format(uint8_t format,
                                   SensorDataFullRecordBody* body)
{
    body->sensor_units_1 &= ~(3 << 6);
    body->sensor_units_1 |= (format & 0x3) << 6;
};

inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
{
    body->m_lsb = m & 0xff;
    body->m_msb_and_tolerance &= ~(3 << 6);
    body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
};
inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
{
    body->m_msb_and_tolerance &= ~0x3f;
    body->m_msb_and_tolerance |= tol & 0x3f;
};

inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
{
    body->b_lsb = b & 0xff;
    body->b_msb_and_accuracy_lsb &= ~(3 << 6);
    body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
};
inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
{
    // bottom 6 bits
    body->b_msb_and_accuracy_lsb &= ~0x3f;
    body->b_msb_and_accuracy_lsb |= acc & 0x3f;
    // top 4 bits
    body->accuracy_and_sensor_direction &= 0x0f;
    body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
};
inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
{
    body->accuracy_and_sensor_direction &= ~(3 << 2);
    body->accuracy_and_sensor_direction |= (exp & 3) << 2;
};
inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
{
    body->accuracy_and_sensor_direction &= ~(3 << 0);
    body->accuracy_and_sensor_direction |= (dir & 3);
};

inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
{
    body->r_b_exponents &= 0xf0;
    body->r_b_exponents |= exp & 0x0f;
};
inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
{
    body->r_b_exponents &= 0x0f;
    body->r_b_exponents |= (exp & 0x0f) << 4;
};

inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
{
    body->id_string_info &= ~(0x1f);
    body->id_string_info |= len & 0x1f;
};
inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
{
    return body->id_string_info & 0x1f;
};
inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
{
    body->id_string_info &= ~(3 << 6);
    body->id_string_info |= (type & 0x3) << 6;
};

inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
{
    body->deviceIDLen &= ~(LENGTH_MASK);
    body->deviceIDLen |= len & LENGTH_MASK;
};

inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
{
    return body->deviceIDLen & LENGTH_MASK;
};

inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
{
    body->discrete_reading_setting_mask[1] = mask & 0x3F;
}

} // namespace body

// More types contained in section 43.17 Sensor Unit Type Codes,
// IPMI spec v2 rev 1.1
enum SensorUnitTypeCodes
{
    SENSOR_UNIT_UNSPECIFIED = 0,
    SENSOR_UNIT_DEGREES_C = 1,
    SENSOR_UNIT_VOLTS = 4,
    SENSOR_UNIT_AMPERES = 5,
    SENSOR_UNIT_WATTS = 6,
    SENSOR_UNIT_JOULES = 7,
    SENSOR_UNIT_METERS = 34,
    SENSOR_UNIT_REVOLUTIONS = 41,
};

struct SensorDataFullRecord
{
    SensorDataRecordHeader header;
    SensorDataRecordKey key;
    SensorDataFullRecordBody body;
} __attribute__((packed));

/** @struct SensorDataFruRecord
 *
 *  FRU Device Locator Record - SDR Type 11
 */
struct SensorDataFruRecord
{
    SensorDataRecordHeader header;
    SensorDataFruRecordKey key;
    SensorDataFruRecordBody body;
} __attribute__((packed));

} // namespace get_sdr

namespace ipmi
{

namespace sensor
{

/**
 * @brief Map offset to the corresponding bit in the assertion byte.
 *
 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
 * byte and offsets 8-14 in the second byte.
 *
 * @param[in] offset - offset number.
 * @param[in/out] resp - get sensor reading response.
 */
inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
{
    if (offset > 7)
    {
        resp->assertOffset8_14 |= 1 << (offset - 8);
    }
    else
    {
        resp->assertOffset0_7 |= 1 << offset;
    }
}

/**
 * @brief Set the reading field in the response.
 *
 * @param[in] offset - offset number.
 * @param[in/out] resp - get sensor reading response.
 */
inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp)
{
    resp->reading = value;
}

/**
 * @brief Map the value to the assertion bytes. The assertion states are stored
 *        in 2 bytes.
 *
 * @param[in] value - value to mapped to the assertion byte.
 * @param[in/out] resp - get sensor reading response.
 */
inline void setAssertionBytes(uint16_t value,
                              ipmi::sensor::GetReadingResponse* resp)
{
    resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF);
    resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8);
}

/**
 * @brief Set the scanning enabled bit in the response.
 *
 * @param[in/out] resp - get sensor reading response.
 */
inline void enableScanning(ipmi::sensor::GetReadingResponse* resp)
{
    resp->operation = 1 << 6;
}

} // namespace sensor

} // namespace ipmi
