"""
AES SDK for networkValide.

Requires: pip install pycryptodome
Format: data = base64(iv + AES-256-CBC-PKCS7(raw_data))
Sign:   md5(data + app_key)
"""

import base64
import hashlib
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes


def _key(aes_key: str) -> bytes:
    return hashlib.sha256(aes_key.encode("utf-8")).digest()


def _pad(data: bytes) -> bytes:
    n = 16 - len(data) % 16
    return data + bytes([n]) * n


def _unpad(data: bytes) -> bytes:
    n = data[-1]
    if n < 1 or n > 16:
        raise ValueError("bad padding")
    return data[:-n]


def encrypt_data(raw_data: str, aes_key: str) -> str:
    iv = get_random_bytes(16)
    cipher = AES.new(_key(aes_key), AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(_pad(raw_data.encode("utf-8")))
    return base64.b64encode(iv + encrypted).decode("ascii")


def decrypt_msg(msg: str, aes_key: str) -> str:
    raw = base64.b64decode(msg)
    iv, encrypted = raw[:16], raw[16:]
    cipher = AES.new(_key(aes_key), AES.MODE_CBC, iv)
    return _unpad(cipher.decrypt(encrypted)).decode("utf-8")


def make_sign(data: str, app_key: str) -> str:
    return hashlib.md5((data + app_key).encode("utf-8")).hexdigest()
