// puzzle_state.h — master-side aggregation of solved puzzles + assembled code.
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#define PUZZLE_MAX_ID       8
#define PUZZLE_MAX_FRAG     4

typedef struct {
    bool    solved[PUZZLE_MAX_ID + 1];
    uint8_t frag[PUZZLE_MAX_ID + 1][PUZZLE_MAX_FRAG];
    uint8_t frag_len[PUZZLE_MAX_ID + 1];
} puzzle_state_t;

void puzzle_state_init(puzzle_state_t *s);

// Record a solved puzzle. Idempotent per id. `len` <= PUZZLE_MAX_FRAG.
// `fragment` pointer must be non-NULL when len > 0. No internal NULL checks.
// A len == 0 fragment is valid — the puzzle is marked solved and contributes no digits.
void puzzle_state_report(puzzle_state_t *s, uint8_t id,
                         const uint8_t *fragment, uint8_t len);

// Write the assembled code (digits of all solved puzzles, by ascending id)
// as a NUL-terminated string. Returns the number of digits written.
// Each fragment byte is taken modulo 10 to produce a decimal digit.
// If cap == 0, nothing is written and 0 is returned.
int puzzle_state_code(const puzzle_state_t *s, char *out, size_t cap);
