#ifndef prototype1_src_l1_5_core_input_olproga_h
#define prototype1_src_l1_5_core_input_olproga_h

#include "../../../gen/l1/OptionU64.h"
#include "../../../gen/l1/VecAndSpan_U8.h"

void stdin_skip_whitespaces(){
    while (true) {
        int ch = fgetc(stdin);
        if (ch == EOF)
            return;
        if (ch < 0) {
            perror("fgetc(stdin)");
            abort();
        }
        if (ch != ' ' && ch != '\t' && ch != '\n') {
            ungetc(ch, stdin);
            break;
        }
    }
}

// Aborts on error
OptionU64 stdin_read_U64(){
    stdin_skip_whitespaces();
    U64 x = 0;
    int i = 0;
    for (;; i++) {
        int ch = fgetc(stdin);
        if (ch == EOF)
            break;
        if (ch < 0) {
            perror("fgetc(stdin)");
            abort();
        }
        if (!('0' <= ch && ch <= '9')) {
            ungetc(ch, stdin);
            break;
        }
        U64 d = (U64)(ch - '0');
        if (x == 0 && i > 0)
            abortf("Bad integer input\n");
        if (x > UINT64_MAX / 10)
            abortf("Integer input exceeds UINT64_MAX\n");
        x *= 10;
        if (x > UINT64_MAX - d)
            abortf("Integer input exceeds UINT64_MAX\n");
        x += d;
    }
    if (i > 0)
        return Some_U64(x);
    return None_U64();
}

/* If empty string is returned it means EOF was reached */
NODISCARD VecU8 stdin_read_VecU8_nospace(){
    stdin_skip_whitespaces();
    VecU8 str = VecU8_new();
    while (true) {
        int ch = fgetc(stdin);
        if (ch == EOF)
            break;
        if (ch < 0) {
            perror("fgetc(stdin)");
            abort();
        }
        if (ch == ' ' || ch == '\t' || ch == '\n') {
            ungetc(ch, stdin);
            break;
        }
        VecU8_append(&str, ch);
    }
    return str;
}

// Aborts if non-integer input or EOF was encountered before my integer
U64 stdin_read_U64_nofail(){
    OptionU64 x = stdin_read_U64();
    if (x.variant == Option_None)
        abortf("No number found\n");
    return x.some;
}


#endif