def update_user(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout,
                    refresh, rows_per_page, url, user_medias, user_type, timezone, role_name, override_passwd):

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        user_ids = {}

        request_data = {
            'userid': zbx_user[0]['userid'],
            'alias': alias,
            'name': name,
            'surname': surname,
            'usrgrps': user_group_ids,
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }

        if override_passwd:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name) if role_name else None
            request_data['timezone'] = timezone

        request_data, _del_keys = helper_normalize_data(request_data)

        # In the case of zabbix 3.2 or less, it is necessary to use updatemedia method to update media.
        if LooseVersion(self._zbx_api_version) <= LooseVersion('3.2'):
            try:
                user_ids = self._zapi.user.update(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e))

            try:
                if user_medias:
                    user_ids = self._zapi.user.updatemedia({
                        'users': [{'userid': zbx_user[0]['userid']}],
                        'medias': user_medias
                    })
            except Exception as e:
                self._module.fail_json(msg="Failed to update user medias %s: %s" % (alias, e))

        if LooseVersion(self._zbx_api_version) >= LooseVersion('3.4'):
            try:
                if user_medias:
                    request_data['user_medias'] = user_medias
                user_ids = self._zapi.user.update(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e))

        return user_ids
    def add_user(self, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout, refresh,
                 rows_per_page, url, user_medias, user_type, not_ldap, timezone, role_name):

        if role_name is None and LooseVersion(self._zbx_api_version) >= LooseVersion('5.2'):
            # This variable is to set the default value because the module must have a backward-compatible.
            # The default value will be removed at the version 2.0.0.
            # https://github.com/ansible-collections/community.zabbix/pull/382
            role_name = "User role"

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        user_ids = {}

        request_data = {
            'alias': alias,
            'name': name,
            'surname': surname,
            'usrgrps': user_group_ids,
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }
        if user_medias:
            request_data['user_medias'] = user_medias

        if LooseVersion(self._zbx_api_version) < LooseVersion('4.0') or not_ldap:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name)
            request_data['timezone'] = timezone

        request_data, _del_keys = helper_normalize_data(request_data)

        diff_params = {}
        if not self._module.check_mode:
            try:
                user_ids = self._zapi.user.create(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to create user %s: %s" % (alias, e))
        else:
            diff_params = {
                "before": "",
                "after": request_data
            }

        return user_ids, diff_params
    def user_parameter_difference_check(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme,
                                        autologin, autologout, refresh, rows_per_page, url, user_medias, user_type,
                                        timezone, role_name, override_passwd):

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        # existing data
        existing_data = copy.deepcopy(zbx_user[0])
        usrgrpids = []
        for usrgrp in existing_data['usrgrps']:
            usrgrpids.append({'usrgrpid': usrgrp['usrgrpid']})

        existing_data['usrgrps'] = sorted(usrgrpids, key=lambda x: x['usrgrpid'])

        # Processing for zabbix 4.0 and above.
        # In zabbix 4.0 and above, Email sendto is of type list.
        # This module, one media supports only one Email sendto.
        # Therefore following processing extract one Email from list.
        if LooseVersion(self._zbx_api_version) >= LooseVersion('4.0'):
            for media in existing_data['medias']:
                if isinstance(media['sendto'], list):
                    media['sendto'] = media['sendto'][0]

        existing_data['user_medias'] = sorted(existing_data['medias'], key=lambda x: x['sendto'])
        for del_key in ['medias', 'attempt_clock', 'attempt_failed', 'attempt_ip', 'debug_mode', 'users_status',
                        'gui_access']:
            del existing_data[del_key]

        for user_media in existing_data['user_medias']:
            for del_key in ['mediaid', 'userid']:
                del user_media[del_key]

        # request data
        request_data = {
            'userid': zbx_user[0]['userid'],
            'alias': alias,
            'name': name,
            'surname': surname,
            'usrgrps': sorted(user_group_ids, key=lambda x: x['usrgrpid']),
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }

        if user_medias:
            request_data['user_medias'] = sorted(user_medias, key=lambda x: x['sendto'])
        else:
            del existing_data['user_medias']

        if override_passwd:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name) if role_name else None
            request_data['timezone'] = timezone

        request_data, del_keys = helper_normalize_data(request_data)
        existing_data, _del_keys = helper_normalize_data(existing_data, del_keys)

        user_parameter_difference_check_result = True
        if existing_data == request_data:
            user_parameter_difference_check_result = False

        diff_params = {
            "before": existing_data,
            "after": request_data
        }

        return user_parameter_difference_check_result, diff_params