# -*- coding: windows-1251 -*-
import threading
from datetime import date, datetime
from xmlrpclib import Fault


def description(my_typ):
    if my_typ == int:
        return 'int'
    elif my_typ == str:
        return 'str'
    elif my_typ == date or my_typ == datetime:
        return 'date'
    elif my_typ == float:
        return 'float'
    elif my_typ == bool:
        return 'bool'


class callback(object):
    def __init__(self):
        self.executing = threading.Lock()
        self.exec_me = threading.Event()
        self.executed = threading.Event()
        self.f_name = ""
        self.f_func = False
        self.f_args = []
        self.f_res = None

    def execute(self, f_name, f_args=[], func_typ=None):
        """Main fuction for using from Python

        DO NOT use any variable on target (TB)
        as order of executing is undefined
        """
        self.executing.acquire(True)
        self.f_name = f_name
        self.f_args = f_args
        if not isinstance(func_typ, basestring):
            func_typ = description(func_typ)
        self.f_func = func_typ
        self.exec_me.set()
        self.executed.wait()
        self.executed.clear()
        res = self.f_res
        self.executing.release()
        if isinstance(res, Fault):
            raise res
        return res

    def _dispatch(self, method, params):
        if method == 'execute':
            return self.execute(*params)
        else:
            return self.execute(method, params)
