import re
import uuid


class UUIDObj:
    __slots__ = ('_raw',)

    def __init__(self, val):
        if val is None:
            self._raw = None
        elif isinstance(val, UUIDObj):
            self._raw = val._raw
        elif isinstance(val, uuid.UUID):
            self._raw = val
        elif isinstance(val, bytes):
            self._raw = uuid.UUID(bytes=val) if len(val) == 16 else uuid.UUID(bytes=val[:16])
        elif isinstance(val, str):
            self._raw = uuid.UUID(val)
        else:
            self._raw = uuid.UUID(str(val))

    @property
    def str(self):
        if self._raw is None:
            return None
        return str(self._raw)

    @property
    def bytes(self):
        if self._raw is None:
            return None
        return self._raw.bytes

    @property
    def uuid(self):
        return self._raw

    def __str__(self):
        return self.str or ''

    def __repr__(self):
        return f'UUIDObj({self.str})'

    def __eq__(self, other):
        if isinstance(other, UUIDObj):
            return self._raw == other._raw
        if isinstance(other, uuid.UUID):
            return self._raw == other
        if isinstance(other, str):
            return self.str == other
        if isinstance(other, bytes) and len(other) == 16:
            return self.bytes == other
        return NotImplemented

    def __hash__(self):
        return hash(self._raw)

    def __bool__(self):
        return self._raw is not None
