---

- name: update over multiple reboots
  block:
    - block:
        - name: install all windows updates
          win_updates:
            category_names: "{{ win_update_category_names }}"
            blacklist: "{{ (win_update_blacklist | default([])) + (failed_kb | default([])) }}"
            whitelist: "{{ win_update_whitelist | default(omit) }}"
            reboot: yes
          register: installed_updates

      rescue:
        - name: reboot the system to recover from a failed update
          win_reboot:
            reboot_timeout: 7200

        - name: set failed KB to skip
          set_fact:
            failed_kb: "{{ failed_kb|default([]) + [installed_updates.msg | regex_replace('^.*\\((KB.*)\\).*','\\1')] }}"
          when:
            - installed_updates.msg is defined
            - ('Failed' in installed_updates.msg)
            - ('KB' in installed_updates.msg)

        - name: fail to retry
          fail:
            msg: "There are failed updates: {{ failed_kb | join(' ') }}"
          when:
            - failed_kb is defined
            - failed_kb | length > 0

    - name: wait for system to be responsive after update
      wait_for_connection:
        delay: 60
        sleep: 10
        timeout: 600

    - name: work on any skipped KB
      win_updates:
        category_names: "{{ win_update_category_names }}"
        blacklist: "{{ win_update_blacklist | default(omit) }}"
        whitelist: "{{ failed_kb | default([]) }}"
        reboot: yes
      register: installed_updates_retry_skipped
      when:
        - failed_kb is defined
        - failed_kb | length > 0

    - name: check for missing updates
      win_updates:
        category_names: "{{ win_update_category_names }}"
        blacklist: "{{ win_update_blacklist | default(omit) }}"
        state: searched
      register: missing_updates

    - debug:
        msg: |
          {{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
          {% for key, value in missing_updates.updates.items() %}
            - {{ value.title }}
          {% endfor %}
      when: missing_updates.updates is defined

    - name: still more updates - need to retry
      fail:
        msg: >
          '{{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
          {{ (update_retry_limit | int) - (update_retry_count | int) }} more retries left'
      when:
        - missing_updates.found_update_count > 0
        - ((update_retry_limit | int) - (update_retry_count | int) >= 0)

  rescue:
    - name: set update count
      set_fact:
        update_retry_count: '{{ update_retry_count | default(0) | int + 1 }}'

    - debug:
        msg: "Still more updates remaining - retrying... ({{ update_retry_count }}/{{ update_retry_limit }})"

    - include_tasks: updates-with-retry.yml
      when: ((update_retry_limit | int) - (update_retry_count | int) >= 0)