/* additional types for expenses grammar
 */
#pragma once
#include <stdio.h>
#include <time.h>
#include <glib.h>

typedef enum BotCommand {
    BOT_CMD_IN,
    BOT_CMD_OUT,
    BOT_CMD_DELETE,
    BOT_CMD_REPORT
} BotCommand;

typedef enum BotReportTimespan {
    BOT_TS_DAILY,
    BOT_TS_WEEKLY,
    BOT_TS_MONTHLY,
    BOT_TS_YEARLY
} BotReportTimespan;

typedef struct BotExpenseEntry {
    unsigned int id;
    struct tm time;                /* number of seconds since the epoch, needs `localtime()` + timezone to localize: https://stackoverflow.com/questions/1442116/how-can-i-get-the-date-and-time-values-in-a-c-program */
    double value;               /* positive or negative according to in or out */
    double totalAmount;         /* keep track of the total amount at this point */
    bool _serialized;            /* utility to check if entry has been serialized before freeing */
    GString *user;
    GString *notes;
} BotExpenseEntry;

/* Parser definitions */
int yylex();
int yyparse();
int yylex_destroy();
typedef struct yy_buffer_state * YY_BUFFER_STATE;
YY_BUFFER_STATE yy_scan_string(const char * str);

/* Parse a string with Flex+Bison instead of a file / stdout */
int grammar_parse_string(const GString *buf);

/* Create a BotExpenseEntry with data fed from the parser. If 'previous' is null, initialize as first expense and 'totalAmount' will be 0 */
BotExpenseEntry *create_bot_expense_entry
(
 const BotExpenseEntry *previous,
 const BotCommand cmd,
 const double value,
 GString* user,
 GString* notes
);

/* FP should not be null */
GString *serialize_bot_expense_entry_csv
(
  BotExpenseEntry *data
);

/* returns the number of bytes written, following the convention of fprintf */
int write_bot_expense_entry
(
 FILE *fp,
 BotExpenseEntry *entry
);
