"""
Compatibility tools for differences between Python 2 and 3
"""

import platform
import sys

asunicode = lambda x, _: str(x)  # noqa:E731

PYTHON_IMPL_WASM = (
    sys.platform == "emscripten" or platform.machine() in ["wasm32", "wasm64"]
)

__all__ = [
    "asunicode",
    "asstr",
    "asbytes",
    "lmap",
    "lzip",
    "lrange",
    "lfilter",
    "with_metaclass",
    "PYTHON_IMPL_WASM",
]


def asbytes(s):
    if isinstance(s, bytes):
        return s
    return s.encode("latin1")


def asstr(s):
    if isinstance(s, str):
        return s
    return s.decode("latin1")


# list-producing versions of the major Python iterating functions
def lrange(*args, **kwargs):
    return list(range(*args, **kwargs))


def lzip(*args, **kwargs):
    return list(zip(*args, **kwargs))


def lmap(*args, **kwargs):
    return list(map(*args, **kwargs))


def lfilter(*args, **kwargs):
    return list(filter(*args, **kwargs))


def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    # This requires a bit of explanation: the basic idea is to make a dummy
    # metaclass for one level of class instantiation that replaces itself with
    # the actual metaclass.
    class metaclass(meta):
        def __new__(cls, name, this_bases, d):
            return meta(name, bases, d)

    return type.__new__(metaclass, "temporary_class", (), {})
