#ifndef KEKS_SCHEMA_H
#define KEKS_SCHEMA_H

#include <stddef.h>

#include "items.h" // IWYU pragma: keep // struct KEKSItems

// TEXINFO: KEKSSchemaErrType
// @deftp {Data type} {enum KEKSSchemaErrType}
// Data validation against schema error type.
// @itemize
// @item KEKSSchemaErrInvalid -- invalid item value, uninitialised
// @item KEKSSchemaErrNo -- no error
// @item KEKSSchemaErrInvalidSchema -- bad schema format itself
// @item KEKSSchemaErrUnexpectedState -- schema lead to unexpected state
// @item KEKSSchemaErrInvalidData -- data structure is invalid
// @end itemize
// @end deftp
enum KEKSSchemaErrType {
    KEKSSchemaErrInvalid = 0,
    KEKSSchemaErrNo = 1,
    KEKSSchemaErrInvalidSchema,
    KEKSSchemaErrUnexpectedState,
    KEKSSchemaErrInvalidData,
};

// TEXINFO: KEKSSchemaErr
// @deftp {Data type} {struct KEKSSchemaErr}
// Data validation against schema error details.
// @table @code
// @item .code
//     Error code.
// @item .msg
//     Optional human readable message.
// @item .offSchema
//     Offset of the failed command in the schema.
// @item .offData
//     Offset of the failed element in the data.
// @end table
// @end deftp
struct KEKSSchemaErr {
    size_t offSchema;
    size_t offData;
    const char *msg;
    enum KEKSSchemaErrType code;
    char _pad[4];
};

// TEXINFO: KEKSSchemaValidate
// @deftypefun {struct KEKSSchemaErr} KEKSSchemaValidate @
//     (const struct KEKSItems *schema, @
//      struct KEKSItems *data, @
//      size_t idxSchema, @
//      size_t idxData)
// Validate decoded @var{data} against the decoded @var{schema}.
// @var{idxSchema} points to the MAP-item of the root schema you wish to
// check against. @var{idxData} points to the item of the data you are
// going to sanitise (0 in most cases).
// @end deftypefun
struct KEKSSchemaErr
KEKSSchemaValidate(
    const struct KEKSItems *schema,
    struct KEKSItems *data,
    size_t idxSchema,
    size_t idxData);

#endif // KEKS_SCHEMA_H
