#ifndef ODIN_BUFFER_HPP
#define ODIN_BUFFER_HPP

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#include "vtr_memory.h"

#define CHUNK_SIZE 128
/* General Utility methods ------------------------------------------------- */

class dynamic_buffer_t
{
private:
	char *str = NULL;
	size_t len = 0;
public:


    void push(char in)
    {
        if(this->len % CHUNK_SIZE == 0)
        {
            this->str = (char*) vtr::realloc(this->str, sizeof(char) * (this->len + CHUNK_SIZE));
            memset(&this->str[this->len], 0, CHUNK_SIZE);
        }

        this->str[this->len] = in;	
        this->len += 1;
    }

    char *dump_str()
    {
        char *temp = str;
        str = NULL;
        return temp;
    }
    
};


class buffered_reader_t
{
private:
    FILE *source = NULL;

    bool eof = false;
    bool multiline_comment = false;

    const char *one_line_comment = "";
    size_t one_line_comment_len = 0;

    const char *n_line_comment_ST = "";
    size_t n_line_comment_ST_len = 0;

    const char *n_line_comment_END = "";
    size_t n_line_comment_END_len = 0;

    size_t buffer_size = 2;

    static bool is_eof(int in)
    {
        return (EOF == in);
    }

    static bool is_nl(int in)
    {
        return is_eof(in) || ('\n' == (char)in || '\r' == (char)in);
    }

    static bool is_whitespace(int in)
    {
        return is_nl(in) || ( ' ' == (char)in || '\t' == (char)in);
    }

    bool is_one_line_comment(const char *in)
    {
        return (one_line_comment_len && strncmp (in, one_line_comment, one_line_comment_len) == 0);
    }

    bool is_n_line_comment_ST(const char *in)
    {
        return (n_line_comment_ST_len && strncmp (in, n_line_comment_ST, n_line_comment_ST_len) == 0);
    }

    bool is_n_line_comment_END(const char *in)
    {
        return (n_line_comment_END_len && strncmp (in, n_line_comment_END, n_line_comment_END_len) == 0);
    }

    buffered_reader_t(){}

public:
    buffered_reader_t(FILE *_source, const char *_one_line_comment, const char *_n_line_comment_ST, const char *_n_line_comment_END)
    {
        this->source = _source;

        if(_one_line_comment)
        {
            this->one_line_comment = _one_line_comment;
            this->one_line_comment_len = strlen(_one_line_comment);
        }
        
        if(_n_line_comment_ST && _n_line_comment_END)
        {
            this->n_line_comment_ST = _n_line_comment_ST;
            this->n_line_comment_END = _n_line_comment_END;
            
            this->n_line_comment_ST_len = strlen(_n_line_comment_ST);
            this->n_line_comment_END_len = strlen(_n_line_comment_END);
        }

        this->buffer_size = (
            std::max((size_t)2, // for whitespace duplicate
            std::max(one_line_comment_len,
            std::max(n_line_comment_ST_len,
                    n_line_comment_END_len)))
        );
    }

    /*
    * Reads a line from a file stream character-by-character
    * to dynamically build a string.
    * strip duplicate whitespace
    * skip comments
    */
    char* get_line()
    {
        char *line = NULL;

        if(!(eof))
        {
            dynamic_buffer_t my_line;

            char *buffer = (char*) vtr::calloc(this->buffer_size, sizeof(char));

            bool single_line_comment = false;
            size_t skip_count = this->buffer_size-1;
            bool eol = false;

            bool first_write = true;

            // trim head and compress
            while( !is_nl(buffer[0]) )
            {
                int c = '\n';
                if(!eol && !(eof))
                    c = fgetc(source);

                for(int i = 1; i < this->buffer_size; i++)
                {
                    buffer[i-1] = buffer[i];
                }

                buffer[this->buffer_size-1] = (char)c;

                eof = (eof || is_eof(c));
                eol = (eol || is_nl(c));

                if(skip_count)
                {
                    skip_count--;
                }
                else if( multiline_comment )
                {
                    if(is_n_line_comment_END(buffer))
                    {
                        multiline_comment = false;
                        skip_count = strlen(n_line_comment_END);
                    }
                }
                else if( single_line_comment )
                {
                    // read until the end
                }
                else if(is_one_line_comment(buffer))
                {
                    single_line_comment = true;
                }
                else if(is_n_line_comment_ST(buffer))
                {
                    multiline_comment = true;
                }
                else if( ! is_whitespace(buffer[0]) )
                {
                    first_write = false;
                    my_line.push(buffer[0]);	
                }
                else if( ! is_whitespace(buffer[1]) )
                {
                    if( ! first_write )
                        my_line.push(' ');	
                }
            } 

            vtr::free(buffer);

            my_line.push('\0');	

            line = my_line.dump_str();
        }

        return line;
    }
};

#endif //ODIN_BUFFER_HPP
