#!python
import argparse
import json
import sys
import vyper

from vyper import compiler, optimizer
from vyper.parser.parser import parse_to_lll
from vyper.parser import parser_utils
from vyper import compile_lll

sys.tracebacklimit = 0

parser = argparse.ArgumentParser(description='Vyper {0} programming language for Ethereum'.format(vyper.__version__))
parser.add_argument('input_file', help='Vyper sourcecode to compile')
parser.add_argument('-f', help='Format to print', choices=['abi', 'json', 'bytecode', 'bytecode_runtime', 'ir', 'asm'], default='bytecode', dest='format')
parser.add_argument('--show-gas-estimates', help='Show gas estimates in ir output mode.', action="store_true")

args = parser.parse_args()


def print_asm(asm_list):
    skip_newlines = 0
    for node in asm_list:
        if isinstance(node, list):
            print_asm(node)
            continue

        is_push = isinstance(node, str) and node.startswith('PUSH')

        print(str(node) + ' ', end='')
        if skip_newlines:
            skip_newlines -= 1
        elif is_push:
            skip_newlines = int(node[4:]) - 1
        else:
            print('')


if __name__ == '__main__':

    with open(args.input_file) as fh:
        code = fh.read()
        if args.show_gas_estimates:
            parser_utils.LLLnode.repr_show_gas = True

        if args.format == 'abi':
            print(compiler.mk_full_signature(code))
        elif args.format == 'json':
            print(json.dumps(compiler.mk_full_signature(code)))
        elif args.format == 'bytecode':
            print('0x' + compiler.compile(code).hex())
        elif args.format == 'bytecode_runtime':
            print('0x' + compiler.compile(code, bytecode_runtime=True).hex())
        elif args.format == 'ir':
            print(optimizer.optimize(parse_to_lll(code)))
        elif args.format == 'asm':
            lll = optimizer.optimize(parse_to_lll(code))
            print_asm(compile_lll.compile_to_assembly(lll))
