import t
import memhub
import string


class _Type:
    def type_id(self) -> int:
        return 99


class _str:
    # 编译期元数据：声明此类希望从 with 上下文获取 __mbuddy__ 字段（非必要，找不到不报错）
    __requires__: list[str] = ['__mbuddy__']
    __data__: str
    __mbuddy__: memhub.MemBuddy | t.CPtr

    def upper(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        for i, ch in enumerate(src):
            if ch >= 97:
                if ch <= 122:
                    buf[i] = ch - 32
                else:
                    buf[i] = ch
            else:
                buf[i] = ch
        buf[length] = 0
        return str(buf)

    def lower(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        for i, ch in enumerate(src):
            if ch >= 65:
                if ch <= 90:
                    buf[i] = ch + 32
                else:
                    buf[i] = ch
            else:
                buf[i] = ch
        buf[length] = 0
        return str(buf)

    def capitalize(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        first: bool = True
        for i, ch in enumerate(src):
            if first:
                first = False
                if ch >= 97:
                    if ch <= 122:
                        buf[i] = ch - 32
                    else:
                        buf[i] = ch
                else:
                    buf[i] = ch
            else:
                if ch >= 65:
                    if ch <= 90:
                        buf[i] = ch + 32
                    else:
                        buf[i] = ch
                else:
                    buf[i] = ch
        buf[length] = 0
        return str(buf)

    def swapcase(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        for i, ch in enumerate(src):
            if ch >= 97:
                if ch <= 122:
                    buf[i] = ch - 32
                else:
                    buf[i] = ch
            else:
                if ch >= 65:
                    if ch <= 90:
                        buf[i] = ch + 32
                    else:
                        buf[i] = ch
                else:
                    buf[i] = ch
        buf[length] = 0
        return str(buf)

    def title(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        prev_alpha: bool = False
        for i, ch in enumerate(src):
            cur_alpha: bool = False
            if ch >= 65:
                if ch <= 90:
                    cur_alpha = True
                else:
                    if ch >= 97:
                        if ch <= 122:
                            cur_alpha = True
            if cur_alpha:
                if prev_alpha:
                    if ch >= 65:
                        if ch <= 90:
                            buf[i] = ch + 32
                        else:
                            buf[i] = ch
                    else:
                        buf[i] = ch
                else:
                    if ch >= 97:
                        if ch <= 122:
                            buf[i] = ch - 32
                        else:
                            buf[i] = ch
                    else:
                        buf[i] = ch
            else:
                buf[i] = ch
            prev_alpha = cur_alpha
        buf[length] = 0
        return str(buf)

    def casefold(self) -> str:
        src: str = self.__data__
        length: t.CSizeT = len(src)
        buf: bytes = self.__mbuddy__.alloc(length + 1)
        if buf == None: return self.__data__
        for i, ch in enumerate(src):
            if ch >= 65:
                if ch <= 90:
                    buf[i] = ch + 32
                else:
                    buf[i] = ch
            else:
                buf[i] = ch
        buf[length] = 0
        return str(buf)

    def isupper(self) -> bool:
        src: str = self.__data__
        has_alpha: bool = False
        for ch in src:
            if ch >= 65:
                if ch <= 90:
                    has_alpha = True
                else:
                    if ch >= 97:
                        if ch <= 122:
                            return False
        return has_alpha

    def islower(self) -> bool:
        src: str = self.__data__
        has_alpha: bool = False
        for ch in src:
            if ch >= 97:
                if ch <= 122:
                    has_alpha = True
            if ch >= 65:
                if ch <= 90:
                    return False
        return has_alpha

    def isalpha(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        for ch in src:
            has_char = True
            cur_alpha: bool = False
            if ch >= 65:
                if ch <= 90:
                    cur_alpha = True
                else:
                    if ch >= 97:
                        if ch <= 122:
                            cur_alpha = True
            if not cur_alpha:
                return False
        return has_char

    def isdigit(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        for ch in src:
            has_char = True
            if ch >= 48:
                if ch > 57:
                    return False
            else:
                return False
        return has_char

    def isalnum(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        for ch in src:
            has_char = True
            ok: bool = False
            if ch >= 48:
                if ch <= 57:
                    ok = True
            if not ok:
                if ch >= 65:
                    if ch <= 90:
                        ok = True
                    else:
                        if ch >= 97:
                            if ch <= 122:
                                ok = True
            if not ok:
                return False
        return has_char

    def isspace(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        for ch in src:
            has_char = True
            is_space: bool = False
            if ch == 32 or ch == 9 or ch == 10 or ch == 13 or ch == 11 or ch == 12:
                is_space = True
            if not is_space:
                return False
        return has_char

    def isascii(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        for ch in src:
            has_char = True
            if ch > 127: return False
        return has_char

    def istitle(self) -> bool:
        src: str = self.__data__
        has_char: bool = False
        prev_alpha: bool = False
        for ch in src:
            has_char = True
            cur_alpha: bool = False
            if ch >= 65:
                if ch <= 90:
                    cur_alpha = True
                else:
                    if ch >= 97:
                        if ch <= 122:
                            cur_alpha = True
            if cur_alpha:
                if not prev_alpha:
                    if ch >= 97:
                        if ch <= 122:
                            return False
                else:
                    if ch >= 65:
                        if ch <= 90:
                            return False
            prev_alpha = cur_alpha
        return has_char

    def split(self, delimiter: str) -> list[str]:
        result = list[str](self.__mbuddy__)
        src: str = self.__data__
        length: t.CSizeT = len(src)
        delim_len: t.CSizeT = string.strlen(delimiter)
        start: t.CSizeT = 0
        i: t.CSizeT = 0
        cur: str = src
        sub_len: t.CSizeT = 0
        sub: bytes = None
        src_off: bytes = None
        term: bytes = None
        if delim_len == 0:
            sub_len = length
            sub = self.__mbuddy__.alloc(sub_len + 1)
            if sub != None:
                src_off = bytes(t.CUInt64T(src) + start)
                string.memcpy(sub, src_off, sub_len)
                term = sub
                term[sub_len] = 0
                result.append(str(sub))
            return result
        while i + delim_len <= length:
            if string.strncmp(cur, delimiter, delim_len) == 0:
                sub_len = i - start
                sub = self.__mbuddy__.alloc(sub_len + 1)
                if sub != None:
                    src_off = bytes(t.CUInt64T(src) + start)
                    string.memcpy(sub, src_off, sub_len)
                    term = sub
                    term[sub_len] = 0
                    result.append(str(sub))
                start = i + delim_len
                cur += delim_len
                i += delim_len
            else:
                cur += 1
                i += 1
        sub_len = length - start
        sub = self.__mbuddy__.alloc(sub_len + 1)
        if sub != None:
            src_off = bytes(t.CUInt64T(src) + start)
            string.memcpy(sub, src_off, sub_len)
            term = sub
            term[sub_len] = 0
            result.append(str(sub))
        return result
