#include "zb_config.h"

#ifdef ZB_BEELIGHT_SUPPORT_CLUSTER_CO2_MEASUREMENT

#include "zb_common.h"
#include "zb_zcl.h"
#include "zb_aps.h"
#include "zb_beelight_co2_cluster.h"

zb_ret_t check_value_co2_measurement_server(zb_uint16_t attr_id, zb_uint8_t endpoint, zb_uint8_t *value);
void zb_beelight_co2_measurement_write_attr_hook_server(zb_uint8_t endpoint, zb_uint16_t attr_id, zb_uint8_t *new_value, zb_uint16_t manuf_code);

void zb_beelight_co2_measurement_init_server(void)
{
    zb_zcl_add_cluster_handlers(ZB_BEELIGHT_CLUSTER_ID_CO2_MEASUREMENT,
                                ZB_ZCL_CLUSTER_SERVER_ROLE,
                                check_value_co2_measurement_server,
                                zb_beelight_co2_measurement_write_attr_hook_server,
                                (zb_zcl_cluster_handler_t)NULL);
}

void zb_beelight_co2_measurement_init_client(void)
{
    zb_zcl_add_cluster_handlers(ZB_BEELIGHT_CLUSTER_ID_CO2_MEASUREMENT,
                                ZB_ZCL_CLUSTER_CLIENT_ROLE,
                                (zb_zcl_cluster_check_value_t)NULL,
                                (zb_zcl_cluster_write_attr_hook_t)NULL,
                                (zb_zcl_cluster_handler_t)NULL);
}

zb_ret_t check_value_co2_measurement_server(zb_uint16_t attr_id, zb_uint8_t endpoint, zb_uint8_t *value)
{
    zb_ret_t ret = RET_OK;
    zb_uint16_t val = ZB_ZCL_ATTR_GET16(value);

    TRACE_MSG(TRACE_ZCL1, "> check_value_co2_measurement, attr_id %d, val %d", (FMT__D_D, attr_id, val));

    switch (attr_id)
    {
        case ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_VALUE_ID:
            if (ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_VALUE_UNKNOWN == val)
            {
                ret = RET_OK;
            }
            else
            {
                zb_zcl_attr_t *attr_desc = zb_zcl_get_attr_desc_a(endpoint,
                    ZB_BEELIGHT_CLUSTER_ID_CO2_MEASUREMENT,
                    ZB_ZCL_CLUSTER_SERVER_ROLE,
                    ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_ID);
                ZB_ASSERT(attr_desc);

                ret = (ZB_ZCL_GET_ATTRIBUTE_VAL_16(attr_desc) == ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_INVALID ||
                    ZB_ZCL_GET_ATTRIBUTE_VAL_16(attr_desc) <= val)
                    ? RET_OK : RET_ERROR;

                if (ret == RET_OK)
                {
                    attr_desc = zb_zcl_get_attr_desc_a(endpoint,
                        ZB_BEELIGHT_CLUSTER_ID_CO2_MEASUREMENT,
                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                        ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_ID);
                    ZB_ASSERT(attr_desc);

                    ret = ZB_ZCL_GET_ATTRIBUTE_VAL_16(attr_desc) == ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_INVALID ||
                            val <= ZB_ZCL_GET_ATTRIBUTE_VAL_16(attr_desc)
                        ? RET_OK : RET_ERROR;
                }
            }
            break;

        case ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_ID:
            ret = ((ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_MIN_VALUE <= val) &&
                    (val <= ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_MAX_VALUE)) ||
                    (ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MIN_VALUE_INVALID == val)
                    ? RET_OK : RET_ERROR;
            break;

        case ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_ID:
            ret = ((ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_MIN_VALUE <= val) &&
                    (val <= ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_MAX_VALUE)) ||
                    (ZB_BEELIGHT_ATTR_CO2_MEASUREMENT_MAX_VALUE_INVALID == val)
                    ? RET_OK : RET_ERROR;
            break;

        default:
            break;
    }

    TRACE_MSG(TRACE_ZCL1, "< check_value_co2_measurement ret %hd", (FMT__H, ret));

    return ret;
}

void zb_beelight_co2_measurement_write_attr_hook_server(
  zb_uint8_t endpoint, zb_uint16_t attr_id, zb_uint8_t *new_value, zb_uint16_t manuf_code)
{
    ZVUNUSED(new_value);
    ZVUNUSED(endpoint);
    ZVUNUSED(manuf_code);

    TRACE_MSG(TRACE_ZCL1, ">> zb_zcl_temp_measurement_write_attr_hook endpoint %hd, attr_id 0x%x, manuf_code 0x%x",
                (FMT__H_D_D, endpoint, attr_id, manuf_code));

    if (attr_id == ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID)
    {
    }

    TRACE_MSG(TRACE_ZCL1, "<< zb_zcl_temp_measurement_write_attr_hook", (FMT__0));
}

#endif /* ZB_BEELIGHT_SUPPORT_CLUSTER_CO2_MEASUREMENT */
