#!/usr/bin/env python

# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
Simple PB Words client demo

This connects to a server (host/port specified by argv[1]/argv[2]),
authenticates with a username and password (given by argv[3] and argv[4]),
joins a group (argv[5]) sends a simple message, leaves the group, and quits
the server.

To run the script:

    $ python pb_client.py <host> <port> <username> <password> <group>

"""

from __future__ import print_function

import sys
from twisted.python import log
from twisted.cred import credentials
from twisted.words import service
from twisted.spread import pb
from twisted.internet import reactor

class DemoMind(service.PBMind):
    """An utterly pointless PBMind subclass.

    This notices messages received and prints them to stdout.  Since
    the bot never stays in a channel very long, it is exceedingly
    unlikely this will ever do anything interesting.
    """
    def remote_receive(self, sender, recipient, message):
        print('Woop', sender, recipient, message)

def quitServer(ignored):
    """Quit succeeded, shut down the reactor.
    """
    reactor.stop()

def leftGroup(ignored, avatar):
    """Left the group successfully, quit the server.
    """
    q = avatar.quit()
    q.addCallback(quitServer)
    return q

def sentMessage(ignored, group, avatar):
    """Sent the message successfully, leave the group.
    """
    l = group.leave()
    l.addCallback(leftGroup, avatar)
    return l

def joinedGroup(group, avatar):
    """Joined the group successfully, send a stupid message.
    """
    s = group.send({"text": "Hello, monkeys"})
    s.addCallback(sentMessage, group, avatar)
    return s

def loggedIn(avatar, group):
    """Logged in successfully, join a group.
    """
    j = avatar.join(group)
    j.addCallback(joinedGroup, avatar)
    return j

def errorOccurred(err):
    """Something went awry, log it and shutdown.
    """
    log.err(err)
    try:
        reactor.stop()
    except RuntimeError:
        pass

def run(host, port, username, password, group):
    """Create a mind and factory and set things in motion.
    """
    m = DemoMind()
    f = pb.PBClientFactory()
    f.unsafeTracebacks = True
    l = f.login(credentials.UsernamePassword(username, password), m)
    l.addCallback(loggedIn, group)
    l.addErrback(errorOccurred)
    reactor.connectTCP(host, int(port), f)

def main():
    """
    Set up logging, have the real main function run, and start the reactor.
    """
    if len(sys.argv) != 6:
        raise SystemExit("Usage: %s host port username password group" % (sys.argv[0],))
    log.startLogging(sys.stdout)

    host, port, username, password, group = sys.argv[1:]
    port = int(port)
    username = username.decode(sys.stdin.encoding)
    group = group.decode(sys.stdin.encoding)

    reactor.callWhenRunning(run, host, port, username, password, group)
    reactor.run()

if __name__ == '__main__':
    main()
