#include "lamp_ui_policy.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>

static unsigned checks;

static void expect(lg_mode current, lamp_ui_button button, bool accepted,
                   lamp_ui_command_kind kind, lg_mode mode,
                   lp_recipe recipe, uint32_t duration) {
    lamp_ui_command command = {
        .kind = LUI_COMMAND_NONE,
        .mode = LG_FAULT,
        .recipe = LP_RECIPE_COUNT,
        .duration_ms = UINT32_C(0xA5A5A5A5)
    };
    bool result = lamp_ui_resolve_button(current, button, &command);
    assert(result == accepted);
    if (accepted) {
        assert(command.kind == kind);
        assert(command.mode == mode);
        assert(command.recipe == recipe);
        assert(command.duration_ms == duration);
    } else {
        assert(command.kind == LUI_COMMAND_NONE);
        assert(command.mode == LG_FAULT);
        assert(command.recipe == LP_RECIPE_COUNT);
        assert(command.duration_ms == UINT32_C(0xA5A5A5A5));
    }
    ++checks;
}

int main(void) {
    expect(LG_OFF, LUI_BUTTON_BASE_COLOR, true, LUI_COMMAND_START_RECIPE,
           LG_AI, LP_BASE_COLOR, 45000u);
    expect(LG_AI, LUI_BUTTON_BUILDER_EXTENSION, true, LUI_COMMAND_START_RECIPE,
           LG_AI, LP_BUILDER_EXTENSION, 90000u);
    expect(LG_AI, LUI_BUTTON_DARK_GEL, true, LUI_COMMAND_START_RECIPE,
           LG_MANUAL, LP_DARK_GEL, 120000u);
    expect(LG_AI, LUI_BUTTON_TOP_COAT, true, LUI_COMMAND_START_RECIPE,
           LG_MANUAL, LP_TOP_COAT, 120000u);
    expect(LG_MANUAL, LUI_BUTTON_BASE_COLOR, true, LUI_COMMAND_START_RECIPE,
           LG_MANUAL, LP_BASE_COLOR, 45000u);
    expect(LG_OFF, LUI_BUTTON_LONG_PRESS_MANUAL, true, LUI_COMMAND_SET_MODE,
           LG_MANUAL, LP_RECIPE_COUNT, 0u);
    expect(LG_MANUAL, LUI_BUTTON_MANUAL_60, true, LUI_COMMAND_START_RECIPE,
           LG_MANUAL, LP_MANUAL_60, 60000u);
    expect(LG_MANUAL, LUI_BUTTON_MANUAL_120, true, LUI_COMMAND_START_RECIPE,
           LG_MANUAL, LP_MANUAL_120, 120000u);
    expect(LG_AI, LUI_BUTTON_MANUAL_60, false, LUI_COMMAND_NONE,
           LG_FAULT, LP_RECIPE_COUNT, 0u);
    expect(LG_FAULT, LUI_BUTTON_DARK_GEL, false, LUI_COMMAND_NONE,
           LG_FAULT, LP_RECIPE_COUNT, 0u);
    expect(LG_FAULT, LUI_BUTTON_CANCEL, true, LUI_COMMAND_STOP,
           LG_FAULT, LP_RECIPE_COUNT, 0u);
    expect(LG_AI, LUI_BUTTON_INVALID, false, LUI_COMMAND_NONE,
           LG_FAULT, LP_RECIPE_COUNT, 0u);
    expect(LG_OFF, LUI_BUTTON_CANCEL, true, LUI_COMMAND_STOP,
           LG_OFF, LP_RECIPE_COUNT, 0u);

    lamp_ui_command sentinel = {
        .kind = LUI_COMMAND_STOP,
        .mode = LG_MANUAL,
        .recipe = LP_MANUAL_120,
        .duration_ms = 120000u
    };
    assert(!lamp_ui_resolve_button(LG_AI, LUI_BUTTON_DARK_GEL, NULL));
    assert(sentinel.kind == LUI_COMMAND_STOP && sentinel.mode == LG_MANUAL &&
           sentinel.recipe == LP_MANUAL_120 && sentinel.duration_ms == 120000u);
    ++checks;
    printf("PASS: SoC button events map to explicit mode/timer commands (%u checks)\n", checks);
    return 0;
}
