import time

from behave import given, then, when

from integration_tests.features.utils import has_value
from plasma_cash.dependency_config import container

userA = '0xb83e232458A092696bE9717045d9A605FB0FEc2b'
userB = '0x08d92dcA9038eA9433254996a2D4F08D43BE8227'
userC = '0xDF29cFbD5d793Fa5B22D5c730A8E8450740C6f8f'
operator_key = '0xa18969817c2cefadf52b93eb20f917dce760ce13b2ac9025e0361ad1e7a1d448'
userA_key = '0xe4807cf08191b310fe1821e6e5397727ee6bc694e92e25115eca40114e3a4e6b'
userB_key = '0xee092298d0c0db61969cc4466d57571cf3ca36ca62db94273d5c1513312aeb30'
eth_currency = '0x0000000000000000000000000000000000000000'
uid = 1693390459388381052156419331572168595237271043726428428352746834777341368960

DEPOSIT_TX_BLOCK = 1
TRANSFER_TX_1_BLOCK = 2
TRANSFER_TX_2_BLOCK = 3


@given('userA deposits {amount:d} eth in plasma cash')
def userA_deposits_some_amount_of_eth_in_plasma_cash(context, amount):
    client = container.get_client()
    client.deposit(
        amount=amount,
        depositor=userA,
        currency=eth_currency
    )
    time.sleep(5)
    client.submit_block(operator_key)


@given('userA transfers {amount:d} eth to userB')
def userA_transfers_some_eth_to_userB(context, amount):
    prev_block = DEPOSIT_TX_BLOCK
    client = container.get_client()
    client.send_transaction(prev_block, uid, amount, userB, userA_key)
    client.submit_block(operator_key)


@given('userB transfers {amount:d} eth to userC')
def userB_transfers_some_eth_to_userC(context, amount):
    prev_block = TRANSFER_TX_1_BLOCK
    client = container.get_client()
    client.send_transaction(prev_block, uid, amount, userC, userB_key)
    client.submit_block(operator_key)


@when('userB starts to exit {amount:d} eth from plasma cash')
def userB_starts_to_exit_some_eth_from_plasma_cash(context, amount):
    client = container.get_client()
    client.start_exit(userB, uid, prev_tx_blk_num=DEPOSIT_TX_BLOCK, tx_blk_num=TRANSFER_TX_1_BLOCK)
    time.sleep(5)
    client.submit_block(operator_key)


@then('root chain got the start-exit record from coin spent challenge')
def root_chain_got_the_start_exit_record_from_coin_spent_challenge(context):
    root_chain = container.get_root_chain()
    assert has_value(root_chain.functions.exits(uid).call({'from': userB}))


@when('userC challenges the coin spent exit')
def userC_challenges_the_coin_spent_exit(context):
    client = container.get_client()
    client.challenge_exit(userC, uid, tx_blk_num=TRANSFER_TX_2_BLOCK)
    time.sleep(5)
    client.submit_block(operator_key)


@then('the challenge is successful and root chain cancels the coin spent exit')
def the_challenge_is_successful_and_root_chain_cancels_the_spent_coin_exit(context):
    root_chain = container.get_root_chain()
    assert not has_value(root_chain.functions.exits(uid).call({'from': userC}))
