#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#


from rmake_test import rmakehelp


import StringIO
import unittest

testFrozenLead1 = '\xbe\xeb\xab\xba\x04\x00\x00\x00\00\00\00\00\00\x00\x00\x02\x00\x01\x05\x00\x04\x00\x01\xe2@\x06\x00\x04\x00\x12\xd6\x87'

testFrozenLead2 = 'this is a bad lead that will miserably fail'

testFrozenHeader1 = 'content-type: binary/xml\n'

testFrozenMessage1 = '\xbe\xeb\xab\xba\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x05\x00\x04\x00\x00\x00(\x06\x00\x04\x00\x00\x00\x16content-type: application/octect-stream\nThis is a test message'

testFrozenMessage2 = "\xbe\xeb\xab\xba\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x05\x00\x04\x00\x00\x00'\x06\x00\x04\x00\x00\x00\x17content-type: application/binary-stuff\nFirst line\nSecond line\n"
testPayload1 = "This is a test message"

class EnvelopeTest(rmakehelp.RmakeHelper):

    def importPlugins(self):
        global envelope
        from rmake.messagebus import envelope

    msgPayloadSize = 1234567
    msgHeaderSize = 123456
    def testLeadFreeze(self):

        f = envelope.PLead()
        f.msgPayloadSize.set(self.msgPayloadSize)
        self.failUnlessEqual(f.msgPayloadSize(), self.msgPayloadSize)
        f.msgHeaderSize.set(self.msgHeaderSize)
        self.failUnlessEqual(f.msgHeaderSize(), self.msgHeaderSize)

        data = f.freeze()
        self.failUnlessEqual(data, testFrozenLead1)

    def testHeaderFreeze(self):
        f = envelope.PHeader()
        f['content-type'] = "binary/xml"
        data = f.freeze()

        self.failUnlessEqual(data, testFrozenHeader1)

        ff = envelope.PHeader()
        ff.thawString(data)
        self.failUnlessEqual(ff['content-type'], "binary/xml")

    def testLeadChunkedThaw(self):
        s1 = StringIO.StringIO(testFrozenLead1[:10])
        s2 = StringIO.StringIO(testFrozenLead1[10:])

        f = envelope.PLead()
        self.failIf(f.thawFromStream(s1.read))
        self.failUnless(f.thawFromStream(s2.read))

        self.failUnlessEqual(f.msgHeaderSize(), self.msgHeaderSize)
        self.failUnlessEqual(f.msgPayloadSize(), self.msgPayloadSize)

    def testLeadThawBad(self):
        f = envelope.PLead()
        self.failUnlessRaises(envelope.BadMagicError, f.thawString, testFrozenLead2)

    def testMessageThawLead(self):
        m = envelope.Envelope()

        s1 = StringIO.StringIO(testFrozenLead1[:10])
        s2 = StringIO.StringIO(testFrozenLead1[10:])

        self.failIf(m.thawLead(s1.read))
        self.failUnless(m.thawLead(s2.read))

    def testMessageThawHeader(self):
        m = envelope.Envelope()

        m.setHeaderSize(len(testFrozenHeader1))

        s1 = StringIO.StringIO(testFrozenHeader1[:4])
        s2 = StringIO.StringIO(testFrozenHeader1[4:])

        self.failIf(m.thawHeader(s1.read))
        self.failUnless(m.thawHeader(s2.read))

    def testMessageFreezeBasic(self):
        m = envelope.Envelope()
        payloadStream = StringIO.StringIO(testPayload1)

        m.setPayloadStream(payloadStream)
        m.setPayloadSize(len(testPayload1))
        payloadStream.seek(0)
        m.setContentType('application/octect-stream')