# 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 hashlib
import re
from collections.abc import ByteString, Iterable, Mapping
from decimal import Decimal
from typing import Optional, Union

from czc import json

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


def kebab_to_title(s: str) -> str:
    return s.replace('-', ' ').title()


def snake_to_kebab(s: str) -> str:
    return s.replace('_', '-')


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, 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)


def get_md5(data: str) -> str:
    md5 = hashlib.md5()
    md5.update(data.encode('utf-8'))
    return md5.hexdigest()
