Manage the SNMP sysContact, sysLocation, and sysServices settings.

    Args:
        contact (str, optional): The SNMP contact.

        location (str, optional): The SNMP location.

        services (list, optional): A list of selected services. The possible
            service names can be found via ``win_snmp.get_agent_service_types``.
            To disable all services pass a list of None, ie: ['None']

    Returns:
        bool: True if successful, otherwise False

    CLI Example:

    .. code-block:: bash

        salt '*' win_snmp.set_agent_settings contact='Contact Name' location='Place' services="['Physical']"

def set_agent_settings(contact=None, location=None, services=None):
    '''
    Manage the SNMP sysContact, sysLocation, and sysServices settings.

    Args:
        contact (str, optional): The SNMP contact.

        location (str, optional): The SNMP location.

        services (list, optional): A list of selected services. The possible
            service names can be found via ``win_snmp.get_agent_service_types``.
            To disable all services pass a list of None, ie: ['None']

    Returns:
        bool: True if successful, otherwise False

    CLI Example:

    .. code-block:: bash

        salt '*' win_snmp.set_agent_settings contact='Contact Name' location='Place' services="['Physical']"
    '''
    if services is not None:
        # Filter services for unique items, and sort them for comparison
        # purposes.
        services = sorted(set(services))

        # Validate the services.
        for service in services:
            if service not in _SERVICE_TYPES:
                message = ("Invalid service '{0}' specified. Valid services:"
                           ' {1}').format(service, get_agent_service_types())
                raise SaltInvocationError(message)

    if six.PY2:
        contact = _to_unicode(contact)
        location = _to_unicode(location)

    settings = {'contact': contact, 'location': location, 'services': services}

    current_settings = get_agent_settings()

    if settings == current_settings:
        _LOG.debug('Agent settings already contain the provided values.')
        return True

    if contact is not None:
        if contact != current_settings['contact']:
            __utils__['reg.set_value'](
                _HKEY, _AGENT_KEY, 'sysContact', contact, 'REG_SZ')

    if location is not None:
        if location != current_settings['location']:
            __utils__['reg.set_value'](
                _HKEY, _AGENT_KEY, 'sysLocation', location, 'REG_SZ')

    if services is not None:
        if set(services) != set(current_settings['services']):
            # Calculate the total value. Produces 0 if an empty list was provided,
            # corresponding to the None _SERVICE_TYPES value.
            vdata = sum(_SERVICE_TYPES[service] for service in services)

            _LOG.debug('Setting sysServices vdata to: %s', vdata)

            __utils__['reg.set_value'](
                _HKEY, _AGENT_KEY, 'sysServices', vdata, 'REG_DWORD')

    # Get the fields post-change so that we can verify tht all values
    # were modified successfully. Track the ones that weren't.
    new_settings = get_agent_settings()
    failed_settings = dict()

    for setting in settings:
        if settings[setting] is not None and \
                    settings[setting] != new_settings[setting]:
            failed_settings[setting] = settings[setting]

    if failed_settings:
        _LOG.error('Unable to configure agent settings: %s', failed_settings)
        return False

    _LOG.debug('Agent settings configured successfully: %s', settings.keys())
    return True