#!/usr/bin/env python3

from __future__ import print_function

from datetime import datetime
import sys

import reflectrpc
import reflectrpc.cmdline

parser = reflectrpc.cmdline.build_cmdline_parser("Generate client code from a running ReflectRPC service")

# Add our program-specific arguments
parser.add_argument("outfile", metavar='OUTFILE', type=str, help="Output file")

args = parser.parse_args()
client = reflectrpc.cmdline.connect_client(args)

(service_description, functions, custom_types) = reflectrpc.cmdline.fetch_service_metainfo(client)

f = open(args.outfile, "w")

f.write('"""\n')
f.write('Auto generated client code for service %s %s\n' %
        (service_description['name'], service_description['version']))
f.write('Description: %s\n' % (service_description['description']))
f.write('Generated at %s (UTC)\n' % (str(datetime.utcnow().replace(microsecond=0))))
f.write('Generated by ReflectRPC (rpcgencode) %s\n' % (reflectrpc.version))

if args.host.startswith('unix://'):
    f.write('Generated from %s\n' % (args.host))
else:
    f.write('Generated from %s:%d\n' % (args.host, args.port))

f.write('"""\n\n')

f.write('from reflectrpc.client import RpcClient\n')
f.write('from reflectrpc.client import RpcError\n\n')

f.write('class ServiceClient(object):\n')
f.write('    def __init__(self):\n')
if args.host.startswith('unix://'):
    f.write("        self.client = RpcClient('%s')\n" % (args.host))
else:
    f.write("        self.client = RpcClient('%s', %d)\n" % (args.host, args.port))

# derive the options for RpcClient from the args with which the user called us
if args.http:
    f.write("        self.client.enable_http(%s)\n" % (args.http_path))

if args.tls:
    f.write("        self.client.enable_tls(%s, %s)\n" % (args.ca, args.check_hostname))

if args.cert and args.key:
    f.write("        self.client.enable_client_auth(%s, %s)\n" % (args.cert, args.key))

f.write('\n')

for i, func_desc in enumerate(functions):
    paramlist = [param['name'] for param in func_desc['params']]
    methodparams = ['self'] + paramlist
    methodparamlist = ', '.join(methodparams)
    paramlist = ', '.join(paramlist)

    f.write('    def %s(%s):\n' % (func_desc['name'], methodparamlist))
    f.write('        """\n')
    f.write('        %s' % (func_desc['description']))
    f.write('\n')
    if len(paramlist):
        f.write('\n')
        f.write('        Args:\n')
    for param in func_desc['params']:
        f.write('            %s (%s): %s\n' % (param['name'],
            reflectrpc.json2py(param['type']), param['description']))
    f.write('\n')
    f.write('        Returns:\n')
    f.write('            %s: %s\n\n' % (reflectrpc.json2py(func_desc['result_type']), func_desc['result_desc']))
    f.write('        Raises:\n')
    f.write('            RpcError: Error returned by the server\n')
    f.write('        """\n')
    if len(paramlist):
        f.write("        return self.client.rpc_call('%s', %s)" % (func_desc['name'], paramlist))
    else:
        f.write("        return self.client.rpc_call('%s')" % (func_desc['name']))

    if i < len(functions) - 1:
        f.write('\n\n')

f.close()
