import json
import socket

class Client:
    def __init__(self, addr):
        self.s = socket.create_connection(addr)
        self.f = self.s.makefile('r')
        self.id = 0

    def call(self, method, *args):
        req = {
            'id': self.id,
            'method': method,
            'params': list(args),
        }
        msg = json.dumps(req) + '\n'
        self.s.sendall(msg.encode('ascii'))
        return json.loads(self.f.readline())

def guess_type(arg):
    if arg.lower() == "true":
        return True
    if arg.lower() == "false":
        return False
    if arg.isdigit():
        return int(arg)
    if arg.lower() == "null":
        return None
    try:
        return float(arg)
    except Exception as _:
        pass
    return arg

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--default', choices=['nexa', 'bch'])
    parser.add_argument('--port', action='store')
    parser.add_argument('--server', action='store')
    parser.add_argument('method')
    parser.add_argument('args', nargs='*')
    args = parser.parse_args()

    # Define defaults per chain
    chainDefaults = {
        "nexa" : {
            "port" : "20001",
            "server" : "rostrum.nexa.org"
        },
        "bch" : {
            "port" : "50001",
            "server" : "bitcoincash.network"
        },
    }

    # Falls back to Nexa mainnet, in case no --default or --server and --port is set
    port = chainDefaults["nexa"]["port"]
    server = chainDefaults["nexa"]["server"]

    # If --default argument is used, set chain default using the dict chainDefaults
    if args.default:
        port = chainDefaults[args.default]["port"]
        server = chainDefaults[args.default]["server"]

    # Use --port argument if set, potentially overriding the --default argument
    if args.port:
        port = args.port

    # Use --server argument if set, potentially overriding the --default argument
    if args.server:
        server = args.server

    forward_args = map(guess_type, args.args)

    conn = Client((server, port))
    print(json.dumps(conn.call(args.method, *forward_args), indent=2))
