#!/usr/bin/env python


# https://twistedmatrix.com/documents/16.2.0/core/howto/defer.html

from twisted.internet import reactor, defer
from twisted.python.failure import Failure
from pprint import pprint

def getData(inputData):
    print('getData({0})'.format(inputData))
    deferred = defer.Deferred()
    # simulate a delayed result by asking reactor
    # to fire in 2 seconds with inputData * 3 as result
    print("return result in 1 sec...")
    reactor.callLater(1, deferred.callback, inputData+1)
    return deferred

def cbPrint(result):
    print("cbPrint({0})".format(result))
    # doing eferred, or the return result + 1 works
    print("return result (x+1) in 1 sec...")
    deferred = defer.Deferred()
    if result % 2 == 0:
        reactor.callLater(1, deferred.callback, result + 1)
    else:
        reactor.callLater(2, deferred.errback, ValueError("You used an odd number!"))
    return deferred
    # return result + 1

def ePrint(result):
    """ Errback message received here.
    
    However, I get little to no control over this.
    I don't get anything (other then the error itself),
    so I can't do much with the deferred.

    I'm not sure how this is useful.
    """

    print("ERROR:", result)
    # return twisted.python.failure.Failure
    # return Failure
    # return ValueError("Errback handlying sucks...")

d = getData(1)
# Ok, chaining callbacks is ... different.

d.addCallback(cbPrint)
# d.addErrback(ePrint)

d.addCallback(cbPrint)
# d.addErrback(ePrint)

d.addCallback(cbPrint)
# d.addErrback(ePrint)

d.addCallback(cbPrint)
d.addErrback(ePrint)

print("Stop the reactor in 15 seconds...")
reactor.callLater(15, reactor.stop)
print("starting the reactor")
reactor.run()


print("Reactor has been safely shutdown.  :P")