#include <math.h>

#include "quantity.h"
#include "chip.h"


const Quantity QUANTITY_NO_DATA = {
    .unit = UNIT_UNKNOWN,
    .type = QUANTITY_TYPE_ERROR,
    .value_error = CHIP_ERROR_NO_DATA,
};


double quantity_value_as_double(const Quantity *quantity) {

    switch (quantity->type) {

        case QUANTITY_TYPE_UINT32:
            return (double)(quantity->value_uint32);

        case QUANTITY_TYPE_INT32:
            return (double)(quantity->value_int32);

        case QUANTITY_TYPE_FLOAT:
            return (double)(quantity->value_float);

    }

    return NAN;

}

int quantity_convert_to_unit(Quantity *quantity, unit_t dst_unit) {

    if (dst_unit == UNIT_SENSOR_DEFAULT || quantity->type == QUANTITY_TYPE_ERROR) {
        return 0;
    }

    unit_t src_unit = quantity->unit;

    if (src_unit == dst_unit) {
        return 0;
    }

    double value = quantity_value_as_double(quantity);

    int error = unit_convert(&value, src_unit, dst_unit);
    if (error) {
        return error;
    }

    quantity->value_float = (float)value;
    quantity->type = QUANTITY_TYPE_FLOAT;
    quantity->unit = dst_unit;

    return 0;

}

void quantity_convert_to_float(Quantity *quantity) {

    switch (quantity->type) {

        case QUANTITY_TYPE_FLOAT:
        case QUANTITY_TYPE_ERROR:
            return;

        case QUANTITY_TYPE_UINT32:
            quantity->value_float = (float)(quantity->value_uint32);
            break;

        case QUANTITY_TYPE_INT32:
            quantity->value_float = (float)(quantity->value_int32);
            break;

    }

    quantity->type = QUANTITY_TYPE_FLOAT;

}
