from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import msgpack

from .constants import KEY, IV

def _decrypt(ciphertext: bytes) -> bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    plaintext = cipher.decrypt(ciphertext)
    return plaintext

def decrypt_and_unpack(ciphertext: bytes) -> dict:
    decrypted = _decrypt(ciphertext)
    try:
        return msgpack.unpackb(decrypted[:-decrypted[-1]],strict_map_key = False)
    except IndexError:
        print(decrypted)
        exit(1)

def _encrypt(plaintext: bytes) -> bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, iv=IV)
    ciphertext: bytes = cipher.encrypt(pad(plaintext, 16))
    return ciphertext

def encrypt_and_pack(data: dict) -> bytes:
    packed = msgpack.packb(data, use_bin_type = True)
    return _encrypt(packed)

def character_from_id(character_id: int) -> str:
    characters_list = [ # found this easier than a match case. so sue me!
        "Hoshino Ichika",
        "Tenma Saki",
        "Mochizuki Honami",
        "Hinomori Shiho",
        "Hanasato Minori",
        "Kiratani Haruka",
        "Momoi Airi",
        "Hinomori Shizuku",
        "Azusawa Kohane",
        "Shiraishi An",
        "Shinonome Akito",
        "Aoyagi Toya",
        "Tenma Tsukasa",
        "Otori Emu",
        "Kusanagi Nene",
        "Kamishiro Rui",
        "Yoisaki Kanade",
        "Asahina Mafuyu",
        "Shinonome Ena",
        "Akiyama Mizuki",
        "Hatsune Miku",
        "Kagamine Rin",
        "Kagamine Len",
        "Megurine Luka",
        "MEIKO",
        "KAITO"
    ]
    return characters_list[character_id - 1]