#pragma once

#include <string>
#include <memory>

class BufferedReader {
 public:
     explicit BufferedReader(PackageStream *stream) : stream(stream),
                    buffer(new char[stream->PackageLen() + 1]) {
        memset(this->buffer, 0, this->stream->PackageLen() + 1);
        auto length = this->stream->ReadPackage(buffer);
        while (length > 0) {
            this->data += string(this->buffer);
            memset(this->buffer, 0, stream->PackageLen() + 1);
            length = this->stream->ReadPackage(this->buffer);
        }
    }
    int32_t Read(char *output_buffer, int32_t buffer_len) {
        auto new_position = min(static_cast<int32_t>(this->data.size()),
                                this->position + buffer_len);
        auto length = new_position - position;
        memcpy(output_buffer, this->data.c_str() + this->position, length);
        this->position = new_position;
        return length;
    }
    ~BufferedReader() {
        delete[] this->buffer;
    }

 private:
    PackageStream *stream;
    char* buffer;
    string data;
    int32_t position = 0;
};