"""
Name: echo.py
Description: An echo server.
"""

# It imports basic objects.
from untwisted.network import *
from untwisted.utils.stdio import *

class EchoServer(object):
    """ A protocol abstraction for Echo protocol. """
    def __init__(self, spin):
        # It is basically spin.link.
        xmap(spin, ACCEPT, self.handle_accept)
       

    def handle_accept(self, server, client):
        """ When clients connect we are called. """

        # Install the basic protocol stdin to send data
        # asynchronously.
        Stdin(client)

        # Install the basic protocol stdout to receive
        # data asynchronously.
        Stdout(client)
       
        # The LOAD event is generated by Stdout
        # whenever some data is avaialable.
        xmap(client, LOAD, self.handle_load)

        # The CLOSE event is issued by either Stdin 
        # or Stdout protocol. It is when the host lost connection.
        xmap(client, CLOSE, self.handle_close)

    def handle_load(self, client, data):
        """ I dump back what it was written to me. """
        client.dump(data)

    def handle_close(self, client, err):
        """ I am called when the connection is lost. """
        # It tells untwisted to take this spin off the list
        # for reading, writting sockets.
        client.destroy()

        # Just closes the socket.
        client.close()

if __name__ == '__main__':
    # We create a Spin class pretty much as we would
    # do with a socket class.
    spin = Spin()
    spin.bind(('', 1234))
    spin.listen(200)


    # Install the Server protocol. This protocol is used
    # When we want to listen for incoming connections. 
    # It generates the ACCEPT event that happens
    # when some client connected.
    Server(spin)


    # Install the EchoServer application into spin.
    # Some applications might have a dual character
    # in the sense of spawning events through its circuit.
    # it isnt the case actually.
    EchoServer(spin)
    core.gear.mainloop()


