########################################################################
#
#  Copyright (C) 2009, CZ.NIC, z.s.p.o.
# 
#  This file is part of dnstester.
#
#  dnstester is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  dnstester is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
########################################################################

import gtk
import urllib
import math

import config
import lang
import misc

total_weight = 0.0
for w in config.weights.values(): total_weight += w


class Test:

    PHASE_START = 1
    PHASE_DONE = 2

    progress_widget = None
    name = None
    groupname = None
    phase = None

    msg = ""
    result = None

    def __init__(self):
        self.progress_widget = gtk.HBox()


    def clickable_testname(self):
        event_box = gtk.EventBox()
        test_label = gtk.Label("<span color=\"blue\"><u>%s</u></span>" % self.name)
        test_label.set_use_markup(True)
        event_box.add(test_label)
        event_box.connect("button-press-event", self.cb_openpage, None)
        return event_box


    def update_phase(self, phase):
        self.phase = phase
        self.clear_progress_widget()
        hbox = self.progress_widget

        if phase == self.PHASE_START:
            event_box = self.clickable_testname()
            label = gtk.Label(' ' + lang.get_string('test_pending'))
            hbox.pack_start(gtk.Label('  '), False, False, 0)
            hbox.pack_start(event_box, False, False, 0)
            hbox.pack_start(label, False, False, 0)
        elif phase == self.PHASE_DONE:
            hbox.pack_start(self.result_widget(), False, False, 0)

        hbox.show_all()


    def cb_openpage(self, widget, event, data):
        misc.openurl(misc.get_test_desc_base_url() + self.groupname())


    def clear_progress_widget(self):
        children = self.progress_widget.get_children()
        for c in children: self.progress_widget.remove(c)


    def get_progress_widget(self):
        return self.progress_widget


    def msg_add(self, msg):
        self.msg += msg + "\n"


    def set_result(self, result):
        self.result = result


    def encoded_result(self):
        # abstract method
        raise Exception('abstract method call: Test.encoded_result')


    def get_weight(self):

        return config.weights[self.name] / total_weight 


    def result_widget(self, known_better = False):
        # abstract method
        raise Exception('abstract method call: Test.report_line')

    def groupname(self):
        return self.name.split('.')[0].lower()


class TestBoolean(Test):

    def __init__(self, name):
        Test.__init__(self)
        self.name = name


    def is_known_better(self, known_tests):
        if not known_tests: return False
        if self.result: return False
        name = 'test_' + self.name.replace('.', '_')
        if known_tests.has_key(name):
            return known_tests[name] == '1'
        else:
            return False


    def result_widget(self, known_better = False):

        hbox = gtk.HBox()
        if known_better:
            star = '*'
        else:
            star = ''

        event_box = self.clickable_testname()
        w = int(math.ceil(self.get_weight() * 100))
        if self.result:
            label = gtk.Label(" %s (%s %d%%)" % (lang.get_string('pass'), lang.get_string('weight'), w))
        else:
            label = gtk.Label(" %s%s (%s %d%%)" % (lang.get_string('failed'), star, lang.get_string('weight'), w))

        hbox.pack_start(gtk.Label('  '), False, False, 0)
        hbox.pack_start(event_box, False, False, 0)
        hbox.pack_start(label, False, False, 0)
        hbox.show_all()

        return hbox


    def encoded_result(self):
        if self.result:
            return '1'
        else:
            return '0'


