#ifndef LEXER_STATES_H
#define LEXER_STATES_H

#include "aliases.h"
#include <stdbool.h>

#define VALID_JSON true
#define INVALID_JSON false

typedef const char *str_view_t;

typedef enum {
  TK_NO_TOKEN,
  TK_L_BRACE,
  TK_R_BRACE,
  TK_L_BRACKET,
  TK_R_BRACKET,
  TK_NULL,
  TK_BOOL,
  TK_STR_KEY,
  TK_STR_VAL,
  TK_INTEGER,
  TK_DOUBLE,
} token_type;

typedef union {
  void *no_val;
  i64 num_int;
  f64 num_frac;
  str_view_t string;
  bool boolean;
} token_value_t;

typedef struct {
  u64 line;
  u64 column;
  token_type type;
  token_value_t value;
} token_t;

typedef enum {
  LEX_ERR_NONE,
  LEX_ERR_INVALID,
} lex_err_type;

typedef struct {
  lex_err_type errno;
  str_view_t msg;
} lex_err_t;

typedef struct {
  lex_err_t error;
  token_t token;
} lex_result_t;

typedef struct lexer_s lexer_t;

void lexer_init(lexer_t **lexer);
void lexer_free(lexer_t **lexer);
lex_result_t get_next_token(lexer_t *lexer, const char *text);

void print_token(token_t token);

#endif // !LEXER_STATES_H