#include "lamp_guard_wire_adapter.h"

#include <string.h>

static bool reject_invalid(lg_guard *guard, uint32_t now_ms)
{
    const lg_frame invalid = {0};
    return lg_accept_ai(guard, &invalid, now_ms);
}

bool lg_accept_ai_decoded_result(lg_guard *guard, const aiw_result *result,
                                 uint32_t now_ms)
{
    lg_frame frame = {0};
    bool hand_present;

    if (guard == NULL) {
        return false;
    }
    if (result == NULL || result->channels == 0u ||
        result->channels > LG_MAX_CHANNELS ||
        (result->status_flags & (uint8_t)~AIW_RESULT_ALLOWED_FLAGS) != 0u) {
        return reject_invalid(guard, now_ms);
    }

    hand_present = (result->status_flags & AIW_RESULT_FLAG_HAND_PRESENT) != 0u;
    if (!hand_present) {
        for (uint16_t i = 0u; i < result->channels; ++i) {
            if (result->pwm[i] != 0u) {
                return reject_invalid(guard, now_ms);
            }
        }
    }

    frame.session_id = result->session_id;
    frame.ticket_id = result->ticket_id;
    frame.capture_baseline_seq = result->capture_baseline_seq;
    frame.source_frame_seq = result->source_frame_seq;
    frame.calibration_id = result->calibration_id;
    frame.channels = result->channels;
    frame.hand_present = hand_present;
    memcpy(frame.pwm, result->pwm, result->channels);
    return lg_accept_ai(guard, &frame, now_ms);
}

bool lg_accept_ai_packet(lg_guard *guard, const uint8_t *packet, size_t length,
                         uint32_t now_ms)
{
    aiw_result result;
    if (!aiw_decode_result(packet, length, &result)) {
        return reject_invalid(guard, now_ms);
    }
    return lg_accept_ai_decoded_result(guard, &result, now_ms);
}
