# -*- Mode: Python; test-case-name: flumotion.test.test_greeter -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# Flumotion - a streaming media server
# Copyright (C) 2004,2005 Fluendo, S.L. (www.fluendo.com). All rights reserved.

# This file may be distributed and/or modified under the terms of
# the GNU General Public License version 2 as published by
# the Free Software Foundation.
# This file is distributed without any warranty; without even the implied
# warranty of merchantability or fitness for a particular purpose.
# See "LICENSE.GPL" in the source distribution for more information.

# Licensees having purchased or holding a valid Flumotion Advanced
# Streaming Server license may use this file in accordance with the
# Flumotion Advanced Streaming Server Commercial License Agreement.
# See "LICENSE.Flumotion" in the source distribution for more information.

# Headers in this file shall remain intact.

import common

from twisted.spread import jelly
from twisted.trial import unittest
from twisted.internet import reactor

try:
    import gobject
    import gtk
except RuntimeError:
    import os
    os._exit(0)

from flumotion.admin.gtk import greeter, wizard

INTERVAL = 10 # in ms
timeouts = 0

class WizardTest(unittest.TestCase):
    _failed = False
    state = False

    def testMakeGreeter(self):
        wiz = greeter.Greeter()
        ass = self.assert_
        ass(isinstance(wiz, wizard.Wizard))
        ass(isinstance(wiz.name, str))
        ass(isinstance(wiz.page, wizard.WizardStep))
        ass(isinstance(wiz.pages, dict))
        ass(isinstance(wiz.page_stack, list))
        ass(isinstance(wiz.state, dict))

        WINDOW = wiz.window

        def ass(expr):
            if not expr:
                raise # to show the backtrace
                self._failed = True

        def sensitive(w):
            return w.get_property('sensitive')

        # makes sure proc only gets called once
        def idle_add(proc):
            def proc_star():
                proc()
                return False
            gobject.idle_add(proc_star)

        def timeout_add(proc):
            def proc_star():
                proc()
                return False

            global timeouts
            gobject.timeout_add(timeouts * INTERVAL, proc_star)
            timeouts += 1
        
        def find_widget(parent, name):
            if parent.get_name() == name:
                return parent

            if isinstance(parent, gtk.Container):
                for kid in parent.get_children():
                    found = find_widget(kid, name)
                    if found:
                        return found
                
            return None
            
        def call(name, method, *args, **kwargs):
            def check():
                w = find_widget(WINDOW, name)
                assert w
                m = getattr(w, method)
                m(*args, **kwargs)
            timeout_add(check)

        def assert_call_returns(name, method, val, *args, **kwargs):
            def check():
                w = find_widget(WINDOW, name)
                assert w
                m = getattr(w, method)
                ass(m(*args, **kwargs) == val)
            timeout_add(check)

        def click(name):
            call(name, 'emit', 'clicked')

        def set_text(name, text):
            call(name, 'set_text', text)

        def prev():
            click('button_prev')
        def next():
            click('button_next')
        
        def check_prev_next(can_prev, can_next):
            def assert_sensitive(name, s):
                assert_call_returns(name, 'get_property', s, 'sensitive')
            assert_sensitive('button_prev', can_prev)
            assert_sensitive('button_next', can_next)
            
        def check_text(name, text):
            assert_call_returns(name, 'get_text', text)

        check_prev_next(False, True)
        click('connect_to_existing')
        next()
        prev()
        next()
        check_prev_next(True, True)
        set_text('host_entry', 'foo')
        check_prev_next(True, True)
        click('ssl_check')
        check_text('port_entry', '8642')
        next()
        prev()
        next()
        check_prev_next(True, False)
        assert_call_returns('auth_method_combo', 'get_active', 0)
        set_text('user_entry', 'bar')
        check_prev_next(True, False)
        set_text('passwd_entry', 'baz')
        check_prev_next(True, True)
        next()

        state = wiz.run()

        assert not self._failed
        wiz.destroy()
        
        refstate = {'passwd': 'baz', 'host': 'foo', 'port': 8642,
                    'use_insecure': True, 'user': 'bar'}
        self.assert_(state == refstate)

        # getto getto getto hack to make the window go away
        lp = gobject.MainLoop()
        gobject.timeout_add(100,lambda:lp.quit())
        lp.run()
