## This file is generated by tempita. Do not modify this file directly or your changes will get overwritten.
## To edit this file edit the template in template/src

from io import BytesIO
from copy import deepcopy
import warnings

from . import __major__
from ._value cimport AbstractBaseImmutableTag
from ._const cimport ID_STRING
from ._util cimport write_string, read_string, BufferContext
if __major__ <= 2:
    from ._util import primitive_conversion
from ._dtype import EncoderType


cdef inline escape(str string):
    return string.replace('\\', '\\\\').replace('"', '\\"')


cdef inline StringTag read_string_tag(BufferContext buffer, bint little_endian, string_decoder: DecoderType):
    cdef StringTag tag = StringTag.__new__(StringTag)
    tag.value_ = read_string(buffer, little_endian, string_decoder)
    return tag


cdef class StringTag(AbstractBaseImmutableTag):
    """A class that behaves like a string."""
    tag_id = ID_STRING

    def __init__(StringTag self, value = ""):
        if isinstance(value, bytes):
            warnings.warn("StringTag no longer takes bytes as input. You will need to decode this to a string before giving it here. The string of the object will be used instead.", DeprecationWarning)
        self.value_ = str(value)

    def __str__(StringTag self):
        return str(self.value_)

    def __eq__(StringTag self, other):
        cdef StringTag other_
        if isinstance(other, StringTag):
            other_ = other
            return self.value_ == other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ == primitive_conversion(other)
        return NotImplemented

    def __reduce__(StringTag self):
        return self.__class__, (self.value_,)

    def __deepcopy__(StringTag self, memo=None):
        return self.__class__(deepcopy(self.value_, memo=memo))

    def __copy__(StringTag self):
        return self.__class__(self.value_)

    def __hash__(StringTag self):
        return hash((self.tag_id, self.value_))

    def __ge__(StringTag self, other):
        cdef StringTag other_
        if isinstance(other, StringTag):
            other_ = other
            return self.value_ >= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a >= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ >= primitive_conversion(other)
        return NotImplemented

    def __gt__(StringTag self, other):
        cdef StringTag other_
        if isinstance(other, StringTag):
            other_ = other
            return self.value_ > other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a > b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ > primitive_conversion(other)
        return NotImplemented

    def __le__(StringTag self, other):
        cdef StringTag other_
        if isinstance(other, StringTag):
            other_ = other
            return self.value_ <= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a <= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ <= primitive_conversion(other)
        return NotImplemented

    def __lt__(StringTag self, other):
        cdef StringTag other_
        if isinstance(other, StringTag):
            other_ = other
            return self.value_ < other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ < primitive_conversion(other)
        return NotImplemented

    @property
    def py_str(StringTag self) -> str:
        """
        A python string representation of the class.
        """
        return self.value_

    @property
    def py_data(self):
        """
        A python representation of the class. Note that the return type is undefined and may change in the future.
        You would be better off using the py_{type} or np_array properties if you require a fixed type.
        This is here for convenience to get a python representation under the same property name.
        """
        return self.py_str

    def __repr__(StringTag self):
        return f"{self.__class__.__name__}(\"{escape(self.py_str)}\")"

    cdef str _to_snbt(StringTag self):
        return f"\"{escape(self.py_str)}\""

    cdef void write_payload(
        StringTag self,
        object buffer: BytesIO,
        bint little_endian,
        string_encoder: EncoderType,
    ) except *:
        write_string(self.value_, buffer, little_endian, string_encoder)

    def __len__(self) -> int:
        return len(self.value_)

    if __major__ <= 2:
        def __getitem__(self, item) -> str:
            warnings.warn(f"__getitem__ is depreciated on StringTag and will be removed in the future. Please use .py_str to achieve the same behaviour.", DeprecationWarning)
            return self.value_[item]

        def __add__(self, other):
            warnings.warn(f"__add__ is depreciated on StringTag and will be removed in the future. Please use .py_str to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) + primitive_conversion(other)

        def __radd__(self, other):
            warnings.warn(f"__radd__ is depreciated on StringTag and will be removed in the future. Please use .py_str to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) + primitive_conversion(self)

        def __mul__(self, other):
            warnings.warn(f"__mul__ is depreciated on StringTag and will be removed in the future. Please use .py_str to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) * primitive_conversion(other)

        def __rmul__(self, other):
            warnings.warn(f"__rmul__ is depreciated on StringTag and will be removed in the future. Please use .py_str to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) * primitive_conversion(self)
