---
- name: Check cluster swarm status
  run_once: true
  block:
    - name: Fetch cluster server swarm info
      delegate_to: "{{ item }}"
      ansible.builtin.command:
        cmd: !unsafe docker info --format '{{json .Swarm}}'
      changed_when: false
      register: _docker_cluster_swarm_state_raw
      loop: "{{ groups.cluster }}"

    - name: Process cluster server swarm info
      vars:
        _docker_cluster_swarm_state: {}
      ansible.builtin.set_fact:
        _docker_cluster_swarm_state: "{{ _docker_cluster_swarm_state | combine({item.item: (item.stdout | from_json)}) }}"
      loop: "{{ _docker_cluster_swarm_state_raw.results }}"
      loop_control:
        label: "{{ item.item }}"

    - name: Identify swarm managers
      vars:
        _docker_cluster_swarm_managers: []
      when: item.value.LocalNodeState == 'active' and item.value.ControlAvailable
      ansible.builtin.set_fact:
        _docker_cluster_swarm_managers: "{{ _docker_cluster_swarm_managers + [item.key] }}"
      loop: "{{ _docker_cluster_swarm_state | dict2items }}"
      loop_control:
        label: "{{ item.key }}"

    - name: Check that swarm managers were discovered
      ansible.builtin.assert:
        that:
          - _docker_cluster_swarm_managers
        fail_msg: >-
          ERROR: None of the member cluster servers ({{ groups.cluster | join(', ') }}) are joined to
          a docker swarm or is a swarm manager. Please join at least one cluster server to a swarm and
          promote it to swarm manager
        success_msg: >-
          Identified {{ _docker_cluster_swarm_managers | count }} swarm managers
          ({{ _docker_cluster_swarm_managers | join(', ') }})

    - name: Determine swarm manager cluster IDs
      vars:
        _docker_cluster_swarm_manager_cluster_ids: []
      ansible.builtin.set_fact:
        _docker_cluster_swarm_manager_cluster_ids: "{{ _docker_cluster_swarm_manager_cluster_ids + [_docker_cluster_swarm_state[item].Cluster.ID] }}"
      loop: "{{ _docker_cluster_swarm_managers }}"

    - name: Check swarm managers are part of the same swarm
      ansible.builtin.assert:
        that:
          - _docker_cluster_swarm_manager_cluster_ids | unique | count == 1
        fail_msg: >-
          ERROR: Swarm managers ({{ _docker_cluster_swarm_managers | join(', ') }}) appear to be
          joined to different swarms
          (IDs {{ _docker_cluster_swarm_manager_cluster_ids | join(', ') }})
        success_msg: >-
          Swarm managers are joined to swarm with ID
          {{ _docker_cluster_swarm_manager_cluster_ids[0] }}

    - name: Determine swarm manager to use for host configuration
      ansible.builtin.set_fact:
        _docker_swarm_manager: "{{ _docker_cluster_swarm_managers[0] }}"

- name: Determine whether host needs to be added to the swarm
  ansible.builtin.set_fact:
    _docker_swarm_needs_join: "{{ not _docker_cluster_swarm_state[inventory_hostname].Cluster.ID | default('') == _docker_cluster_swarm_manager_cluster_ids[0] }}"
