import ctypes
from ctypes import c_ubyte, sizeof, c_int32, c_char_p, POINTER, pointer, string_at

from asts_client import WINDOWS_1251


class Memory:

    def __init__(self, offset: int, length: int):
        self._offset = offset
        self._length = length
        self._border = offset + length

    def __len__(self):
        return self._length

    def _check(self, size: int):
        if self._offset + size > self._border:
            raise IndexError("No more data in buffer")

    def mark(self, backup: int = 0):
        if backup:
            self._offset = backup
        return self._offset

    def skip(self, size: int):
        self._check(size)
        self._offset += size

    def peek(self):
        self._check(sizeof(c_ubyte))
        return c_ubyte.from_address(self._offset).value

    def take(self):
        size = sizeof(c_ubyte)
        self._check(size)
        result = c_ubyte.from_address(self._offset)
        self._offset += size
        return result.value

    def btoi(self):
        size = sizeof(c_int32)
        self._check(size)
        result = c_int32.from_address(self._offset)
        self._offset += size
        return result.value

    def read(self, size: int, strip=False):
        self._check(size)
        # buffer = c_char_p(self._offset).value
        buffer = string_at(self._offset, size)
        self._offset += size
        string = buffer.decode(WINDOWS_1251)
        return string.rstrip() if strip and size > 1 else string
