from math import ceil
import binascii, logging, colorlog


def str_to_bytes(data):
    if isinstance(data, str):
        return data.encode("utf-8")
    return data


def bytes_to_str(value):
    if isinstance(value, str):
        return value
    return value.decode("utf-8")


def int_to_big_endian(value):
    byte_length = max(ceil(value.bit_length() / 8), 1)
    return (value).to_bytes(byte_length, byteorder="big")


def big_endian_to_int(value):
    return int.from_bytes(value, byteorder="big")


def decode_hex(s):
    if isinstance(s, str):
        return bytes.fromhex(s)
    if isinstance(s, (bytes, bytearray)):
        return binascii.unhexlify(s)
    raise TypeError("Value must be an instance of str or bytes")


def encode_hex(b):
    if isinstance(b, str):
        b = bytes(b, "utf-8")
    if isinstance(b, (bytes, bytearray)):
        return str(binascii.hexlify(b), "utf-8")
    raise TypeError("Value must be an instance of str or bytes")


def get_logger():
    logger = logging.getLogger("abci.app")

    if logger.hasHandlers():
        return logger

    formatter = colorlog.ColoredFormatter(
        "%(log_color)s%(levelname)-8s%(reset)s %(white)s%(message)s",
        datefmt=None,
        reset=True,
        log_colors={
            "DEBUG": "cyan",
            "INFO": "green",
            "WARNING": "yellow",
            "ERROR": "red",
            "CRITICAL": "red,bg_white",
        },
        secondary_log_colors={},
        style="%",
    )

    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)

    return logger
