import base64
import os
from tkinter import Tk, ttk

from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Util import Counter

path = "C:/Users/Kratica Rastogi/PycharmProjects/Cryptography/Assignment_3_Cryptography/txt_files/"

# An AES 256 bit key issued by the Bank. Used to transfer funds between wallets.
KBank = 'F25D58A0E3E4436EC646B58B1C194C6B505AB1CB6B9DE66C894599222F07B893'

# A unique number identifying the Wallet B's instance
Wallet_ID_b = int(4321)

def receiving_funds_window():
    """
    This method is used to get the tkinter window UI of wallet B
    :return: window
    """
    window = Tk()
    window.option_add('*Font', 'Helvetica 13')

    window.title('Receiving funds window')

    # create label to enter token
    lb1 = ttk.Label(window, text="Enter Token X:")
    lb1.place(x=10, y=70)

    # create label to verify receiver wallet ID
    lb2 = ttk.Label(window, text="Verify Wallet ID of receiver:")
    lb2.place(x=10, y=170)

    # create label to get updated balance
    lb3 = ttk.Label(window, text="Updated Balance:")
    lb3.place(x=10, y=120)

    # create text box to eneter encrypted token generated by wallet A
    entry1 = ttk.Entry(window, width=60)
    entry1.place(x=130, y=70)

    btn = ttk.Button(window, text="Submit",
                     command=lambda: [decrypted_generate_token_x(text_box1=entry1, label2=lb2, label3=lb3)])
    btn.place(x=300, y=300)

    window.geometry("685x400")
    return window


def decrypted_generate_token_x(text_box1, label2, label3):
    """
    This method will decrypt the the token using aes-256 cbc mode
    :param text_box1: token in string format
    :param label2: verifying receivers wallet ID after decrypting token
    :param label3: Updated balance of receiver
    :return: plain text, WIDb, counter, updated_balance
    """

    # getting aes-256 cbc mode encoded token
    enc = text_box1.get()

    # decypting the encrypted token using aes-256 cbc mode of operation
    enc = base64.b64decode(bytes.fromhex(enc))
    iv = enc[:16]
    cipher = AES.new(bytes.fromhex(KBank), AES.MODE_CBC, iv)
    decrypted = str(cipher.decrypt(enc[16:])).replace('b', '').replace("'", '')

    # taking receivers wallet ID after decrypting token and converting it to integer
    WIDb = int(decrypted[8:16], 16)

    # taking counter after decrypting token and converting it to integer
    counter = int(decrypted[24:32], 16)

    with open(path + "register_WalletA_to_B_record.txt", "r") as f:
        line = (f.readlines()[-1:])
        ctr = int(line[-1].split(sep='\t')[0])
        if ctr == counter and WIDb == Wallet_ID_b:
            label2.config(text="Wallet ID of receiver and counter matched")
        else:
            label2.config(text="Wallet ID of receiver and counter doesn't matched")

        counter_a = ctr + 1
        file = open(path + "register_WalletA_to_B_record.txt", 'a')
        file.write("\n" + str(counter_a))
        file.close()

    # getting the balance of wallet B
    updated_balance = int(open(path + "balanceWallet_B.txt", "r").read())
    if label3 is not None and label3["text"] is not None and label3["text"] is not "" and updated_balance is not None:
        label3.config(text="Updated Balance: %d" % updated_balance)

    return decrypted, WIDb, counter, updated_balance


if __name__ == '__main__':
    w1 = receiving_funds_window()
    w1.mainloop()
