#!/usr/bin/env python

# based on the 'calculator' demo in the Thrift source

import sys, os.path
sys.path.insert(0, os.path.join(os.path.abspath(os.path.split(sys.argv[0])[0]), 'gen-py'))
import tutorial.Calculator
from tutorial.ttypes import Operation, Work
from thrift.transport import TTwisted
from thrift.protocol import TBinaryProtocol

from twisted.internet import reactor, defer
from twisted.internet.protocol import ClientCreator

def gotPing(_):
    print "Ping received"

def gotAddResults(results):
    print "Got results to add()"
    print results

def gotCalculateResults(results):
    print "Got results to calculate()"
    print results

def gotCalculateErrors(error):
    print "Got an error"
    print error.value.why

def gotClient(p):
    client = p.client

    d1 = client.ping().addCallback(gotPing)

    d2 = client.add(1, 2).addCallback(gotAddResults)

    w = Work(num1=2, num2=3, op=Operation.ADD)

    d3 = client.calculate(1, w).addCallbacks(gotCalculateResults,
        gotCalculateErrors)

    w = Work(num1=2, num2=3, op=Operation.SUBTRACT)

    d4 = client.calculate(2, w).addCallbacks(gotCalculateResults,
        gotCalculateErrors)

    w = Work(num1=2, num2=3, op=Operation.MULTIPLY)

    d5 = client.calculate(3, w).addCallbacks(gotCalculateResults,
        gotCalculateErrors)

    w = Work(num1=2, num2=3, op=Operation.DIVIDE)

    d6 = client.calculate(4, w).addCallbacks(gotCalculateResults,
        gotCalculateErrors)

    # This will fire an errback
    w = Work(num1=2, num2=0, op=Operation.DIVIDE)

    d7 = client.calculate(5, w).addCallbacks(gotCalculateResults,
        gotCalculateErrors)

    d8 = client.zip()

    dl = defer.DeferredList([d1, d2, d3, d4, d5, d6, d7, d8])

    dl.addCallback(lambda _: reactor.stop())

if __name__ == '__main__':
    import sys
    if len(sys.argv) != 3:
        print "%s host port" % sys.argv[0]
        sys.exit(1)

    host = sys.argv[1]
    port = int(sys.argv[2])

    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    d = ClientCreator(reactor, TTwisted.ThriftClientProtocol,
        tutorial.Calculator.Client, pfactory).connectTCP(host, port)
    d.addCallback(gotClient)
    reactor.run()
