#pragma once

#include <vector>
#include <string>
#include <cstdint>
#include <stdexcept>
#include <algorithm>

class Blob
{
    using BYTE = unsigned char;

private:
    const std::vector<BYTE> m_blob;
    size_t m_offset;

    // 检查是否有足够的剩余字节
    void checkSize(size_t required) const
    {
        if (m_offset + required > m_blob.size())
        {
            throw std::out_of_range("Insufficient data in blob");
        }
    }

public:
    // 构造函数，接受一个字节向量的引用
    Blob(const std::vector<BYTE> blob) : m_blob(blob), m_offset(0) {}

    // 重置解析偏移量
    void reset() { m_offset = 0; }

    // 获取当前偏移量
    size_t getOffset() const { return m_offset; }

    // 设置偏移量
    void setOffset(size_t offset)
    {
        if (offset > m_blob.size())
        {
            throw std::out_of_range("Offset out of range");
        }
        m_offset = offset;
    }

    // 获取剩余字节数
    size_t remaining() const { return m_blob.size() - m_offset; }

    // 读取一个T类型的数据（适用于基本类型）
    template <typename T>
    T get()
    {
        checkSize(sizeof(T));

        T value;
        std::copy(m_blob.begin() + m_offset,
                  m_blob.begin() + m_offset + sizeof(T),
                  reinterpret_cast<BYTE *>(&value));
        m_offset += sizeof(T);

        return value;
    }

    // 读取int类型
    int32_t getInt() { return get<int32_t>(); }

    // 读取无符号int类型
    uint32_t getUInt() { return get<uint32_t>(); }

    // 读取short类型
    int16_t getShort() { return get<int16_t>(); }

    // 读取无符号short类型
    uint16_t getUShort() { return get<uint16_t>(); }

    // 读取float类型
    float getFloat() { return get<float>(); }

    // 读取double类型
    double getDouble() { return get<double>(); }

    BYTE getByte() { return get<BYTE>(); }

    float get256()
    {
        BYTE buf = get<BYTE>();
        return static_cast<float>(buf);
    }

    // 读取指定长度的字符串
    std::string getString(size_t length)
    {
        checkSize(length);

        std::string str(reinterpret_cast<const char *>(m_blob.data() + m_offset), length);
        m_offset += length;

        return str;
    }

    // 读取以null结尾的字符串
    std::string getNullTerminatedString()
    {
        size_t length = 0;
        size_t pos = m_offset;

        // 查找null终止符
        while (pos < m_blob.size() && m_blob[pos] != '\0')
        {
            pos++;
            length++;
        }

        // 确保找到了终止符
        if (pos >= m_blob.size())
        {
            throw std::runtime_error("Null-terminated string not found");
        }

        // 读取字符串（不包含终止符）
        std::string str(reinterpret_cast<const char *>(m_blob.data() + m_offset), length);
        m_offset = pos + 1; // 跳过终止符

        return str;
    }

    // 读取指定数量的字节
    std::vector<BYTE> getBytes(size_t count)
    {
        checkSize(count);

        std::vector<BYTE> bytes(m_blob.begin() + m_offset, m_blob.begin() + m_offset + count);
        m_offset += count;

        return bytes;
    }
};
