#!/usr/bin/env python
# -*- coding: utf-8 -*-

from framework import run
from twisted.trial import unittest

from twisted.internet import reactor, protocol
from twisted.protocols import loopback
from twisted.internet import defer

from compass.uss.protocols import byteprotocol
from compass.gnsd import GNSServerProtocol
from compass.gnsc import GNSClientProtocol
from compass.uss.message import gnspmsg

dResult = unittest.deferredResult
loopbackFunc = loopback.loopback

class DummyGNSClientProtocol(byteprotocol.ByteMessageProtocol):
    packet=''

    def __init__(self):
        self.conn = defer.Deferred()

    def connectionMade(self):
        self.conn.callback(None)

    def dataReceived(self, data):
        self.packet = data
        self.transport.loseConnection()

def packmsg(name, items):
    m = gnspmsg.GNSPMessage()
    m.setMsgName(name)
    for f,v in items:
        m.body.setField(f, v)
    return m.packed()

def unpackmsg(packet):
    m = gnspmsg.GNSPMessage()
    m.loadMessage(packet)
    return m

class ConnectServerTestCase(unittest.TestCase):

    sendmsg = ('connect', (
            ('system_id', 'sys001'),\
            ('auth_source', 'xyb4567890123456'),\
            ('version', 0x0001),\
            ('time_stamp', '20041109'),\
            ))
    recvmsg = ('connect_resp', (
            ('status', 0x0001),\
            ('version', 0x0001),\
            ))
    def testServer(self):
        server = GNSServerProtocol()
        client = DummyGNSClientProtocol()
        msg = packmsg(self.sendmsg[0], self.sendmsg[1])

        def sendamsg(result):
            client.sendData(msg)

        client.conn.addCallback(sendamsg)
        loopbackFunc(server, client)

        m = unpackmsg(client.packet)
        self.assertEquals(m.msgname, self.recvmsg[0])
        for i,v in self.recvmsg[1]:
            self.assertEquals(m.body.fields[i], v)

class MailCounterServerTestCase(ConnectServerTestCase):
    sendmsg = ('mail_counter', (
            ('uid', 'mail76'),
            ))
    recvmsg = ('mail_counter_resp', (
            ('uid', 'mail76'),
            ('number', 2028),
            ))

class TerminateServerTestCase(ConnectServerTestCase):
    sendmsg = ('terminate', (
            ))
    recvmsg = ('terminate_resp', (
            ))

class TestGNSServerProtocol(GNSServerProtocol):
    #保存收到的报文序列
    packets = []
    def __init__(self):
        GNSServerProtocol.__init__(self)
        self.conn = defer.Deferred()

    def connectionMade(self):
        GNSServerProtocol.connectionMade(self)
        self.conn.callback(None)

    def connectionLost(self, reason):
        pass

    def dataReceived(self, data):
        GNSServerProtocol.dataReceived(self, data)
        self.packets.append(data)
        if unpackmsg(data).msgname == 'terminate':
            self.transport.loseConnection()

class ClientTestCase(unittest.TestCase):

    # 预期服务端应收到的报文序列
    queue = (
            ('connect',
                (
                    ('auth_source', '1234567890123456'),
                    ('version', 256),
                    ('system_id', '123456'),
                    ('time_stamp', '12345678'),
                ),
            ),
            ('mail_counter',
                (
                    ('uid', '1'),
                ),
            ),
            ('terminate',
                (),
            ),
            )

    def testServer(self):
        server = TestGNSServerProtocol()
        client = GNSClientProtocol()
        loopbackFunc(server, client)
        self.assertEquals(len(server.packets), len(self.queue))
        for m, n in zip(server.packets, self.queue):
            m = unpackmsg(m)
            self.assertEquals(m.msgname, n[0])
            for i, v in n[1]:
                self.assertEquals(m.body.fields[i], v)

if '__main__' == __name__:
    run()
