#!python
"""

Join and Quit RNode

"""
import logging
import argparse
import sys
import getpass
import json

from cpc_fusion import Web3
from cpc_fusion.default_contracts import RNode, Campaign

logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger()

cf = Web3(Web3.HTTPProvider('https://civilian.cpchain.io'))
rnode = RNode(cf)
campaign = Campaign(cf)

def join_rnode(args):
    rnode.join(keystorePath=args.keystore)

def quit_rnode(args):
    rnode.quit(keystorePath=args.keystore)

def check_rnode(args):
    if args.addr:
        if rnode.is_rnode(args.addr):
            log.info('This address is RNode')
        else:
            log.info('This address is not RNode')
        return
    log.info('RNode version: %d', rnode.supported_version)
    log.info('RNode locked period: %d min', rnode.period / 60)
    log.info('RNode threshold: %d CPC', cf.fromWei(rnode.threshold, 'ether'))
    log.info('RNodes count: %d', rnode.rnodes_num)


def check_campaign(args):
    log.info('Campaign version: %d', campaign.supported_version)
    log.info('Campaign term-idx: %d', campaign.term_idx)
    log.info('Campaign view-len: %d', campaign.view_len)
    log.info('Campaign term-len: %d', campaign.term_len)
    log.info('Campaign min-noc: %d', campaign.min_noc)
    log.info('Campaign max-noc: %d', campaign.max_noc)

def deploy(args):
    log.info('Start to deploy contract')
    log.info('ABI: %s, keystore: %s', args.abi, args.keystore)
    with open(args.abi, 'r') as fr:
        contract_data = json.load(fr)
    contract = cf.cpc.contract(
        abi=contract_data['abi'], bytecode=contract_data['bytecode'])

    # build tx
    keystorePath = args.keystore
    with open(keystorePath, 'r') as fr:
        ks = json.load(fr)
        addr = cf.toChecksumAddress(ks['address'])
    gas_price = cf.cpc.gasPrice
    nonce = cf.cpc.getTransactionCount(addr)
    estimated_gas = contract.constructor().estimateGas()
    tx = contract.constructor().buildTransaction({
        'gasPrice': gas_price,
        "nonce": nonce,
        "gas": estimated_gas,
        "from": addr,
        "value": cf.toWei(0, 'ether'),
        "type": 0,
        "chainId": 337
    })

    # send tx
    password = getpass.getpass("Please input your password:")
    decrypted_key = cf.cpc.account.decrypt(ks, password)
    password = ""
    signed_txn = cf.cpc.account.signTransaction(tx, decrypted_key)
    tx_hash = cf.cpc.sendRawTransaction(signed_txn.rawTransaction)
            
    # get tx receipt to get contract address
    tx_receipt = cf.cpc.waitForTransactionReceipt(tx_hash)
    address = tx_receipt['contractAddress']
    log.info(f'{contract_data["contractName"]} Address: {address}, Block: {tx_receipt["blockNumber"]}')
    return address

parser = argparse.ArgumentParser()

subparsers = parser.add_subparsers(help="sub-command help")

# RNode
rnode_parser = subparsers.add_parser('rnode', help="RNode contract")
rnode_sub_parser = rnode_parser.add_subparsers(help='rnode sub-command')

query_rnode_parser = rnode_sub_parser.add_parser('check', help='check parameters for rnode contracts')
query_rnode_parser.add_argument('--addr', type=str, help='Check whether this address is RNode')
query_rnode_parser.set_defaults(func=check_rnode)

join_rnode_parser = rnode_sub_parser.add_parser('join', help='Join RNode')
join_rnode_parser.add_argument('--keystore', type=str, help='Path of the keystore file')
join_rnode_parser.set_defaults(func=join_rnode)

quit_rnode_parser = rnode_sub_parser.add_parser('quit', help='Quit RNode')
quit_rnode_parser.add_argument('--keystore', type=str, help='Path of the keystore file')
quit_rnode_parser.set_defaults(func=quit_rnode)

# Campaign
campaign_parser = subparsers.add_parser('campaign', help="Campaign contract")
campaign_sub_parser = campaign_parser.add_subparsers(help='campaign sub-command')

check_campaign_parser = campaign_sub_parser.add_parser('check', help='check parameters for campaign contracts')
check_campaign_parser.set_defaults(func=check_campaign)

# Deploy
deploy_parser = subparsers.add_parser('deploy', help="Deploy contract")
deploy_parser.add_argument('--keystore', type=str, help='Path of the keystore file')
deploy_parser.add_argument('--abi', type=str, help='Path of the keystore file')
deploy_parser.set_defaults(func=deploy)

args = parser.parse_args()
args.func(args)
