#pragma once
#include <vector>

class BufferedReader {
 public:
    explicit BufferedReader(PackageStream* stream) {
        this->str = stream;
    }
    int32_t Read(char* outBuff, int32_t bytes) {
        for (size_t i = 0; i < buffer.size(); i++) {
            if (i == bytes) {
                buffer.erase(buffer.begin(), buffer.begin() + bytes);
                return bytes;
            }
            outBuff[i] = buffer[i];
        }
        int real_bytes = buffer.size();
        char* after_buf = &(outBuff[buffer.size()]);
        int i = 0;
        for (i = 0; i < (bytes - real_bytes) / str->PackageLen(); i++) {
            int str_real_bytes = str->ReadPackage(after_buf);
            if (str_real_bytes < str->PackageLen()) {
                return i * str->PackageLen() + str_real_bytes + real_bytes;
            }
            after_buf = &(after_buf[str_real_bytes]);
        }
        real_bytes += i * str->PackageLen();
        buffer.clear();
        if (real_bytes == bytes) {
            return real_bytes;
        }
        buffer.resize(str->PackageLen());
        int str_real_bytes = str->ReadPackage(buffer.data());
        for (i = 0; i < bytes - real_bytes; i++) {
            if (i == str_real_bytes) {
                buffer.clear();
                return real_bytes + str_real_bytes;
            }
            outBuff[real_bytes + i] = buffer[i];
        }
        buffer.erase(buffer.begin(), buffer.begin() + bytes - real_bytes);
        return bytes;
    }

 private:
    PackageStream* str;
    std::vector<char> buffer;
};