# Copyright (c) 2020 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com

import base64
import gzip
import re
from decimal import Decimal
from typing import ByteString, Iterable, Mapping, Optional, Union

import simplejson as json

_camel_case_regex = re.compile(r'.+?(?:(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|$)')


def camel_case_split(s: str) -> Iterable:
    if not s:
        return []
    matches = _camel_case_regex.finditer(s)
    return [m.group(0) for m in matches]


def camel_to_snake(s: str) -> str:
    return '_'.join(camel_case_split(s)).lower()


def snake_case_split(s: str) -> Iterable:
    if not s:
        return []
    return s.split('_')


def base64_encode(s: str) -> Optional[str]:
    if s is None:
        return None
    encoded = base64.standard_b64encode(s.encode())
    return encoded.decode()


def base64_decode(s: str) -> Optional[str]:
    if s is None:
        return None
    decoded = base64.standard_b64decode(s)
    return decoded.decode()


def vacuum_pack(obj: Mapping, **kwargs) -> ByteString:
    return base64.standard_b64encode(
        gzip.compress(
            json.dumps(
                obj, iterable_as_array=True, tuple_as_array=True,
                use_decimal=True, **kwargs,
            ).encode()))


def vacuum_unpack(s: Union[bytes, str], **kwargs) -> Mapping:
    return json.loads(
        gzip.decompress(
            base64.standard_b64decode(
                s)
        ), parse_constant=Decimal, use_decimal=True, **kwargs)
