#ifndef __HOST_IPMI_SEN_HANDLER_H__
#define __HOST_IPMI_SEN_HANDLER_H__

#include <stdint.h>
#include "types.hpp"

// IPMI commands for net functions.
enum ipmi_netfn_sen_cmds
{
    IPMI_CMD_GET_SDR_INFO       = 0x20,
    IPMI_CMD_GET_SDR            = 0x21,
    IPMI_CMD_RESERVE_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 *);

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;
};

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

} // 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
#endif
