import base64

import bugsnag
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from django.conf import settings


class AES256:
    def __init__(self):
        self.iv = str.encode(settings.AES_256_IV)
        self.key = str.encode(settings.AES_256_KEY)

    def aes_cbc_encrypt(self, plaintext):
        plaintext = str.encode(plaintext)
        backend = default_backend()
        cipher = Cipher(algorithms.AES(self.key), modes.CBC(self.iv), backend=backend)
        encryptor = cipher.encryptor()

        padder = padding.PKCS7(128).padder()
        padded_plaintext = padder.update(plaintext) + padder.finalize()

        ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize()
        return base64.b64encode(ciphertext).decode('utf-8')

    def aes_cbc_decrypt(self, ciphertext):
        backend = default_backend()
        cipher = Cipher(algorithms.AES(self.key), modes.CBC(self.iv), backend=backend)
        decryptor = cipher.decryptor()

        try:
            ciphertext = base64.b64decode(ciphertext)
            decrypted_padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize()

            unpadder = padding.PKCS7(128).unpadder()
            plaintext = unpadder.update(decrypted_padded_plaintext) + unpadder.finalize()

            return plaintext.decode('utf-8')
        except ValueError as _:
            bugsnag.notify(_)
            return None
