# -*- coding: iso-8859-15 -*-

import sys
import unittest

glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)

from GlasnostTestCase import MinimalTestCase

import glasnost.common.faults as faults

import glasnost.proxy.CardsProxy as CardsProxy
import glasnost.proxy.kinds as kinds
import glasnost.proxy.properties as properties
from glasnost.proxy.tools import getProxyForServerRole


cardsProxy = getProxyForServerRole('cards')

class CardsTestCase(MinimalTestCase):
    cardsCount = None

    def setUp(self):
        MinimalTestCase.setUp(self)
        self.cardsCount = cardsProxy.getObjectsCount()

    def tearDown(self):
        try:
            if self.cardsCount is not None:
                self.failUnlessEqual(cardsProxy.getObjectsCount(),
                                     self.cardsCount)
        finally:
            MinimalTestCase.tearDown(self)


class BasicCardsTestCase(CardsTestCase):
    def test01_cardCreationAndDeletion(self):
        """Test card creation and deletion"""

        card = CardsProxy.Card()
        cardId = cardsProxy.addObject(card)
        card = cardsProxy.getObject(cardId)
        cardsProxy.deleteObject(cardId)

    def test02_cardWithOneProperty(self):
        """Test card with one property"""

        card = CardsProxy.Card()
        card.properties = []

        property = properties.Property()
        property.name = 'firstName'
        kind = kinds.String()
        kind.isTranslatable = 0
        property.kind = kind
        card.properties.append(property)

        cardId = cardsProxy.addObject(card)
        card = cardsProxy.getObject(cardId)
        propertyNames = card.getPropertyNames()
        self.failUnlessEqual(propertyNames, ['firstName'])
        self.failUnlessEqual(
            card.getSlot('firstName').getKind().getThingName(), 'String')
        self.failIf(card.getSlot('firstName').getKind().isTranslatable)
        cardsProxy.deleteObject(cardId)

    def test03_newCardWithOnePropertyAndValue(self):
        """Test creating a card with one property and its value"""

        card = CardsProxy.Card()
        card.properties = []

        property = properties.Property()
        property.name = 'greetings'
        kind = kinds.String()
        property.kind = kind
        card.properties.append(property)
        card.getSlot('greetings').setValue('Hello World')
        self.failUnlessEqual(card.getSlot('greetings').getValue(),
                             'Hello World')

        cardId = cardsProxy.addObject(card)
        card = cardsProxy.getObject(cardId)
        propertyNames = card.getPropertyNames()
        self.failUnlessEqual(propertyNames, ['greetings'])
        self.failUnlessEqual(
            card.getSlot('greetings').getKind().getThingName(), 'String')
        self.failUnlessEqual(card.getSlot('greetings').getValue(),
                             'Hello World')
        cardsProxy.deleteObject(cardId)

    def test04_settingPropertyValue(self):
        """Test setting a property value"""

        card = CardsProxy.Card()
        card.properties = []

        property = properties.Property()
        property.name = 'greetings'
        kind = kinds.String()
        property.kind = kind
        card.properties.append(property)

        cardId = cardsProxy.addObject(card)
        card = cardsProxy.getObject(cardId)
        propertyNames = card.getPropertyNames()
        self.failUnlessEqual(propertyNames, ['greetings'])
        self.failUnlessEqual(
            card.getSlot('greetings').getKind().getThingName(), 'String')
        self.failUnlessEqual(card.getSlot('greetings').getValue(), None)

        card.getSlot('greetings').setValue('Hello World')
        self.failUnlessEqual(card.getSlot('greetings').getValue(),
                             'Hello World')

        cardsProxy.modifyObject(card)
        card = cardsProxy.getObject(cardId)
        propertyNames = card.getPropertyNames()
        self.failUnlessEqual(propertyNames, ['greetings'])
        self.failUnlessEqual(
            card.getSlot('greetings').getKind().getThingName(), 'String')
        self.failUnlessEqual(card.getSlot('greetings').getValue(),
                             'Hello World')

        cardsProxy.deleteObject(cardId)

    def test06_settingPropertyValueRemotely(self):
        """Test setting a property value using remote function"""

        card = CardsProxy.Card()
        card.properties = []

        property = properties.Property()
        property.name = 'greetings'
        kind = kinds.String()
        property.kind = kind
        card.properties.append(property)

        cardId = cardsProxy.addObject(card)

        valueHolder = cardsProxy.getObjectSlotValueHolder(
                cardId, 'self.greetings')
        self.failUnlessEqual(valueHolder.value, None)
        valueHolder.value = 'Hello World!'
        cardsProxy.setObjectSlotValueHolder(
                cardId, 'self.greetings', valueHolder)
        valueHolder = cardsProxy.getObjectSlotValueHolder(
                cardId, 'self.greetings')
        self.failUnlessEqual(valueHolder.value, 'Hello World!')

        cardsProxy.deleteObject(cardId)


class ComplexCardsTestCase(CardsTestCase):
    cardId = None

    def checkCard(self, card):
        propertyNames = card.getPropertyNames()
        self.failUnlessEqual(
            propertyNames,
            ['greetings', 'firstName', 'lastName', 'login', 'email'])
        self.failUnlessEqual(
            card.getSlot('greetings').getKind().getThingName(), 'String')
        self.failUnlessEqual(
                card.getSlot('greetings').getKind().tagInEditMode,
                'div-with-label')
        self.failUnlessEqual(
                card.getSlot('greetings').getKind().stateInEditMode,
                'read-write')
        self.failUnlessEqual(card.getSlot('greetings').getValue(),
                             'Hello World')
        self.failUnlessEqual(
            card.getSlot('firstName').getKind().getThingName(), 'String')
        self.failIf(card.getSlot('firstName').getKind().isTranslatable)
        self.failUnlessEqual(card.getSlot('lastName').getKind().getThingName(),
                             'String')
        self.failIf(card.getSlot('lastName').getKind().isTranslatable)
        self.failUnlessEqual(card.getSlot('login').getKind().getThingName(),
                             'String')
        self.failIf(card.getSlot('login').getKind().isTranslatable)
        self.failUnlessEqual(card.getSlot('email').getKind().getThingName(),
                             'Email')

    def setUp(self):
        CardsTestCase.setUp(self)

        card = CardsProxy.Card()
        card.properties = []

        property = properties.Property()
        property.name = 'greetings'
        kind = kinds.String()
        kind.tagInEditMode = 'div' # tagInEdit mode is read-only, so this
                                   # changes must be ignored.
        kind.stateInEditMode = 'read-only' # stateInEdit mode is read-only, so
                                           # this changes must be ignored.
        property.kind = kind
        card.properties.append(property)
        card.getSlot('greetings').setValue('Hello World')

        property = properties.Property()
        property.name = 'firstName'
        kind = kinds.String()
        kind.isTranslatable = 0
        property.kind = kind
        card.properties.append(property)

        property = properties.Property()
        property.name = 'lastName'
        kind = kinds.String()
        kind.isTranslatable = 0
        property.kind = kind
        card.properties.append(property)

        property = properties.Property()
        property.name = 'login'
        kind = kinds.String()
        kind.isTranslatable = 0
        property.kind = kind
        card.properties.append(property)

        property = properties.Property()
        property.name = 'email'
        kind = kinds.Email()
        property.kind = kind
        card.properties.append(property)

        self.cardId = cardsProxy.addObject(card)

    def tearDown(self):
        if self.cardsCount is not None:
            cardsProxy.deleteObject(self.cardId)
        CardsTestCase.tearDown(self)

    def test01_card(self):
        """Test card with several properties"""

        card = cardsProxy.getObject(self.cardId)
        self.checkCard(card)

    def test02_cardImplementation(self):
        """Test implementation of card with several properties"""

        card = CardsProxy.Card()
        card.prototypeIds = [self.cardId]

        cardId = cardsProxy.addObject(card)
        card = cardsProxy.getObject(cardId)
        self.checkCard(card)
        cardsProxy.deleteObject(cardId)

    def test03_cardDepth2Implementation(self):
        """Test depth 2 implementation of card with several properties"""

        cardImplementationIds = []
        prototypeId = self.cardId
        for i in range(2):
            cardI = CardsProxy.Card()
            cardI.prototypeIds = [prototypeId]
            cardIId = cardsProxy.addObject(cardI)
            cardImplementationIds.append(cardIId)
            prototypeId = cardIId

        cardId = cardImplementationIds[-1]
        card = cardsProxy.getObject(cardId)
        self.checkCard(card)
        cardImplementationIds.reverse()
        for cardImplemetationId in cardImplementationIds:
            cardsProxy.deleteObject(cardImplemetationId)

##     def test04_cardDepth10ImplementationPerformance(self):
##         """Test depth 10 implementation performance of card with
##            several properties"""

##         import time
##         startTime = time.time()

##         self.test03_cardDepth10Implementation()

##         duration = time.time() - startTime
##         self.failIf(
##             duration < 2.5,
##             'Card prototyping is faster than before (= %s s)' % duration)
##         self.failIf(
##             duration > 4.0,
##             'Card prototyping is slower than before (= %s s)' % duration)

suite1 = unittest.makeSuite(BasicCardsTestCase, 'test')
suite2 = unittest.makeSuite(ComplexCardsTestCase, 'test')

allTests = unittest.TestSuite((suite1, suite2))

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(allTests)

