from parallels.plesk.utils.xml_rpc.expand import messages
from collections import namedtuple


class ExpandError(Exception):
    def __init__(self, code, message):
        super(ExpandError, self).__init__(messages.ERROR_EXPAND_ERROR % (code, message))
        self.code = code
        self.message = message


class ExpandSystemError(Exception):
    def __init__(self, code, message):
        super(ExpandSystemError, self).__init__(messages.ERROR_EXPAND_SYSTEM_ERROR % (code, message))

        self.error_code = code
        self.error_message = message


class Result(object):
    @staticmethod
    def parse(elem, parse_data = lambda e: None):
        status = elem.findtext('status')
        if status == 'ok':
            return Success(parse_data(elem))
        else:
            code = int(elem.findtext('errcode'))
            message = elem.findtext('errtext')
            return Failure(code, message)


class Success(namedtuple('Success', ('data',))):
    @property
    def ok(self): return True

    def check(self): pass


class Failure(namedtuple('Failure', ('code', 'message'))):
    @property
    def ok(self): return False

    def check(self):
        raise ExpandError(self.code, self.message)
    
    @property
    def data(self):
        self.check()


def parse_result_set(elem, parse_data_function):
    if elem.findtext('system/status') == 'error':
        # handle system error, for example absence of license: return list of a single "Failure" object
        return [Result.parse(elem.find('system'))]
    else:
        return [Result.parse(r, parse_data_function) for r in elem.findall('result')]