import re
from typing import Tuple, Union

import click


def size_to_byte(value: str) -> int:
    """Convert any size to Byte
    >>> size_to_byte('1TB')
    1099511627776
    >>> size_to_byte('5kB')
    5120
    >>> size_to_byte('.5kB')
    512
    >>> size_to_byte('.5 yoyo')
    Traceback (most recent call last):
    ...
    click.exceptions.BadParameter: Invalid unit for size f{value}
    """
    convert = {
        "B": 1,
        "kB": 1024,
        "MB": 1024 * 1024,
        "GB": 1024 * 1024 * 1024,
        "TB": 1024 * 1024 * 1024 * 1024,
    }
    val, unit = strtod(value)

    if val is None:
        val = 1

    if unit is None:
        # No unit, all good
        # we can round half bytes dont really make sense
        return round(val)
    else:
        try:
            multiplicateur = convert[unit]
        except KeyError:
            raise click.BadParameter("Invalid unit for size f{value}")

    # we can round half bytes dont really make sense
    return round(val * multiplicateur)


DBL_RE = re.compile(r"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?")


def strtod(value: str) -> Tuple[Union[float, None], Union[str, None]]:
    """As most as possible close equivalent of strtod(3) function used by postgres to parse parameter values.
    >>> strtod(' A ') == (None, 'A')
    True
    """
    value = str(value).strip()
    match = DBL_RE.match(value)
    if match:
        end = match.end()
        return float(value[:end]), value[end:]
    return None, value
