class StatsHost(API):
    method = "stats_host"
    # TODO: name is between: registeredusers onlineusers
    arguments = [StringArgument('name'), StringArgument('host')]

    def transform_response(self, api, arguments, response):
        return response.get("stat")
class SubscribeRoom(API):
    method = "subscribe_room"
    arguments = [
        StringArgument('user'),
        StringArgument('nick'),
        StringArgument('room'),
        ListArgument('nodes', required=False)
    ]

    def transform_arguments(self, **kwargs):
        nodes = kwargs.pop("nodes")
        if nodes is None or not isinstance(nodes, list):
            nodes = [
                MUCNodes.mucsub_system, MUCNodes.mucsub_subscribers,
                MUCNodes.mucsub_subject, MUCNodes.mucsub_config,
                MUCNodes.mucsub_presence, MUCNodes.mucsub_messages,
                MUCNodes.mucsub_affiliations
            ]
        nd = []
        for v in nodes:
            serializer_class = MUCNodesSerializer
            t = serializer_class().to_api(v)
            nd.append(t)
        kwargs['nodes'] = nd
        return kwargs

    def transform_response(self, api, arguments, response):
        return response.get('nodes')
class GetRoomAffiliation(API):
    method = 'get_room_affiliation'
    arguments = [
        StringArgument('name'),
        StringArgument('service'),
        StringArgument('jid')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('affiliation') == 0
class CreateRoom(API):
    method = 'create_room'
    arguments = [
        StringArgument('name'),
        StringArgument('service'),
        StringArgument('host')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class MucRegisterNick(API):
    method = "muc_register_nick"
    arguments = [
        StringArgument('nick'),
        StringArgument('service'),
        StringArgument('service')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class ResourceNum(API):
    method = "resource_num"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        PositiveIntegerArgument('num')
    ]

    def transform_response(self, api, arguments, response):
        return response.get("resource")
class CheckPassword(API):
    method = "check_password"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('password')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class GetVcard(API):
    method = "get_vcard"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('name')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('content')
class UserSessionInfo(API):
    method = 'user_sessions_info'
    arguments = [StringArgument('user'), StringArgument('host')]

    def transform_response(self, api, arguments, response):
        sessions_info = response.get('sessions_info', [])
        return [
            dict((k, v) for property_k_v in session["session"]
                 for k, v in property_k_v.items()) for session in sessions_info
        ]
class ChangePassword(API):
    method = 'change_password'
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('newpass')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class SetNickname(API):
    method = 'set_nickname'
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('nickname')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class BanAccount(API):
    method = 'ban_account'
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('reason')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class KickSession(API):
    method = "kick_session"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('resource'),
        StringArgument('reason')
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class SetLast(API):
    method = "set_last"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        IntegerArgument('timestamp'),
        StringArgument('status')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class SendStanzaC2S(API):
    method = "send_stanza_c2s"
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('resource'),
        StringArgument('stanza')
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class DeleteRosterItem(API):
    method = 'delete_rosteritem'
    arguments = [
        StringArgument('localuser'),
        StringArgument('localserver'),
        StringArgument('user'),
        StringArgument('server')
    ]

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class SrgUserDel(API):
    method = "srg_user_del"
    arguments = [
        StringArgument("user"),
        StringArgument("host"),
        StringArgument("group"),
        StringArgument("grouphost")
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class SetVcardMulti(API):
    method = "set_vcard2_multi"
    arguments = [
        StringArgument("user"),
        StringArgument("host"),
        StringArgument("name"),
        StringArgument("subname"),
        StringArgument("contents")
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class ProcessRosterItems(API):
    method = "process_rosteritems"
    arguments = [
        StringArgument('action'),
        StringArgument('subs'),
        StringArgument('asks'),
        StringArgument('users'),
        StringArgument('contacts')
    ]

    def transform_response(self, api, arguments, response):
        return response.get("response")
class SrgCreate(API):
    method = "srg_create"
    arguments = [
        StringArgument("group"),
        StringArgument("host"),
        StringArgument("name"),
        StringArgument("description"),
        StringArgument("display")
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class GetRoster(API):
    method = 'get_roster'
    arguments = [StringArgument('user'), StringArgument('server')]

    def transform_response(self, api, arguments, response):
        roster = []
        for contact in response.get('contacts', []):
            contact_details = {}
            for parameter in contact['contact']:
                for key, value in parameter.items():
                    contact_details[key] = value
            roster.append(contact_details)
        return roster
class GetRoomOptions(API):
    method = 'get_room_options'
    arguments = [StringArgument('name'), StringArgument('service')]

    def transform_response(self, api, arguments, response):
        result = {}
        for option_dict in response.get('options', []):
            option = option_dict.get('option')
            if option is None:
                raise ValueError('Unexpected option in response: {}'.format(
                    str(option_dict)))
            name_dict, value_dict = option
            result[name_dict['name']] = value_dict['value']
        return result
class ConvertToYAML(API):
    method = 'convert_to_yaml'
    arguments = [StringArgument('in_file'), StringArgument('out_file')]

    def transform_arguments(self, **kwargs):
        in_file = kwargs.pop('in_file')
        out_file = kwargs.pop('out_file')
        kwargs.update({
            'in': in_file,
            'out': out_file,
        })
        return kwargs

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class Stats(API):
    method = "stats"
    # TODO: name is between: registeredusers onlineusers onlineusersnode uptimeseconds processes
    arguments = [StringArgument('name')]

    def transform_response(self, api, arguments, response):
        return response.get("stat")
class GetRoomAffiliations(API):
    method = 'get_room_affiliations'
    arguments = [StringArgument('name'), StringArgument('service')]

    def transform_response(self, api, arguments, response):
        affiliations = response.get('affiliations', [])
        return [{
            'username':
            subdict['affiliation'][0]['username'],
            'domain':
            subdict['affiliation'][1]['domain'],
            'affiliation':
            Affiliation.get_by_name(subdict['affiliation'][2]['affiliation']),
            'reason':
            subdict['affiliation'][3]['reason'],
        } for subdict in affiliations]
class Register(API):
    method = 'register'
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('password')
    ]

    def validate_response(self, api, arguments, response):
        if response.get('res') == 1:
            username = arguments.get('user')
            raise UserAlreadyRegisteredError(
                'User with username %s already exist' % username)

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class SendMessage(API):
    method = "send_message"
    arguments = [
        StringArgument('type'),
        StringArgument('from'),
        StringArgument('to'),
        StringArgument('subject', required=False),
        StringArgument('body')
    ]

    def transform_arguments(self, **kwargs):
        from_jid = kwargs.pop('from_jid')
        kwargs.update({'from': from_jid})
        return kwargs

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class CheckPasswordHash(API):
    method = 'check_password_hash'
    arguments = [
        StringArgument('user'),
        StringArgument('host'),
        StringArgument('passwordhash'),
        StringArgument('hashmethod')
    ]

    def transform_arguments(self, **kwargs):
        password_hash = format_password_hash_sha(
            password=kwargs.pop('password'))
        kwargs.update({'passwordhash': password_hash, 'hashmethod': 'sha'})
        return kwargs

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0
class StopKindly(API):
    method = "stop_kindly"
    arguments = [
        PositiveIntegerArgument("delay"),
        StringArgument("announcement")
    ]

    def transform_response(self, api, arguments, response):
        return response.get("res") == 0
class ChangeRoomOption(API):
    method = 'change_room_option'
    arguments = [
        StringArgument('name'),
        StringArgument('service'),
        MUCRoomArgument('option'),
        StringArgument('value')
    ]

    def transform_arguments(self, **kwargs):
        option = kwargs.get('option')
        serializer_class = muc_room_options_serializers.get(
            option, StringSerializer)
        kwargs['value'] = serializer_class().to_api(kwargs['value'])
        return kwargs

    def transform_response(self, api, arguments, response):
        return response.get('res') == 0