# File: obja_xmlrpc_client.py
# XML-RPC with an object passed
# An RPC client for the service described in objx_xmlrpc_protocol.txt
# using the "B" (binary) variant of the protocol.
#
# Version 2 - G. Weber, 2009 Oct 17, for Python3.
# Version 1 -  G. Weber 2007

import xmlrpc.client
from math import pi
from io import StringIO
import sys
import pickle
from solid import Sphere, Cube

def start_proxy (server_uri='http://localhost:8000'):
    # Create a server proxy object
    # Server is deprecated, use xmlrpclib.ServerProxy instead
    proxy = xmlrpc.client.ServerProxy(server_uri)
    return proxy

def run (proxy, tracing):
    
    data = [(Cube(10.0), 0.5), (Sphere(9.0), 0.3),
            (Cube(8.0), 0.85), (Sphere(7.0), 1.2)]

    for (obj, density) in data:

        try:

            # Pickle the object, using protocol HIGHEST_PROTOCOL (= 3),
            # returning an efficient binary representation.
            # Then apply the wrapper class Binary
            
            pickled_bin = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
            wrapped_bin = xmlrpc.client.Binary(pickled_bin)
            
            if tracing:
                print("Wrapped pickled object:\n%s" % wrapped_bin)
                print("Request:\n%s" % xmlrpc.client.dumps((wrapped_bin,), "mass"))

            mass = proxy.mass(wrapped_bin, density)

            if tracing:
                print("Response:")
                print(xmlrpc.client.dumps((mass,), methodresponse=True))
                
            print("The mass of %s with density %f is %f" % (obj, density, mass))

        except xmlrpc.client.Fault as e:
            print("Server error: %s, %s" % (e.faultCode, e.faultString))

        except xmlrpc.client.ProtocolError as e:
            print("Protocol error: %s, %s, %s" % (e.url, e.errcode, e.errmsg))

        except Exception as e:
            print("Something went wrong: %s" % str(e))

def usage ():
    print("Usage: python obja_xmlrpc_client.py <server_uri> [trace]")

def main (args):

    print(args)
    
    if len(args) >= 2:
        server_uri = args[1]
        tracing = (len(args) >= 3 and args[2] == 'trace')

        print("server_uri = %s, tracing = %s" % (server_uri, tracing))

        proxy = start_proxy(server_uri)
        run(proxy, tracing)

    else:
        usage()
        sys.exit(2)

if __name__ == '__main__':
    main(sys.argv)
