
from typing import Union

try:
    import idna as idna2008
except ImportError:
    idna2008 = None


def ascii_bytes(data):
    if isinstance(data, str):
        return data.encode('ascii')
    if isinstance(data, bytes):
        return data
    raise TypeError('only str (ascii encoding) and bytes are supported')


def maybe_str(data):
    if isinstance(data, str):
        return data
    if isinstance(data, bytes):
        try:
            return data.decode('ascii')
        except UnicodeDecodeError:
            return data
    raise TypeError('only str (ascii encoding) and bytes are supported')


def parse_name_idna2008(name: str) -> str:
    parts = name.split('.')
    r = []
    for part in parts:
        if part.isascii():
            r.append(part.encode('ascii'))
        elif len(part) > 253:
            raise RuntimeError(
                f"domains can only be less than 253 characters in length not {len(name)}"
            )
        else:
            r.append(idna2008.encode(part))
    return b'.'.join(r)


def parse_name(name: Union[str, bytes]) -> bytes:
    if isinstance(name, str):
        if name.isascii():
            return name.encode('ascii')
        if idna2008 is not None:
            return parse_name_idna2008(name)
        return name.encode('idna')
    if isinstance(name, bytes):
        return name
    raise TypeError('only str and bytes are supported')


__all__ = ['ascii_bytes', 'maybe_str', 'parse_name']

