---

# Reason for noqa: A double brace might also occur in an awk command sequence.
- name: Check RHEL 7 package groups
  block:
  - name: Set yum group list installed command # noqa var-spacing
    set_fact:
      __sap_preconfigure_fact_yum_group_list_installed_command_assert: "yum group list installed hidden ids |
        awk '/Installed Groups:/{a=1}/Done/{a=0}{if (a==1&&!/:/){print $NF}}' |
        sed 's,(,,;s,),,'"

# Reason for noqa: The command to be executed might contain pipes
  - name: Check if required RHEL 7 package groups are installed # noqa command-instead-of-shell
    shell: "{{ __sap_preconfigure_fact_yum_group_list_installed_command_assert }}"
    register: __sap_preconfigure_register_yum_group_assert
    changed_when: no
    args:
      warn: false

  - name: Assert that all required RHEL 7 package groups are installed
    assert:
      that: "'{{ line_item }}' in __sap_preconfigure_register_yum_group_assert.stdout_lines"
      fail_msg: "FAIL: Package group '{{ line_item }}' is not installed!"
      success_msg: "PASS: Package group '{{ line_item }}' is installed."
    loop: "{{ sap_preconfigure_packagegroups | map('replace', '@', '') | list }}"
    loop_control:
      loop_var: line_item
    ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"

  when:
    - sap_preconfigure_packagegroups|d([])
    - ansible_os_family == 'RedHat'
    - ansible_distribution_major_version == '7'

# Reason for noqa: A double brace might also occur in an awk command sequence.
- name: Check RHEL 8 environment groups
  block:
    - name: Set yum envgroup list installed command # noqa var-spacing
      set_fact:
        __sap_preconfigure_fact_yum_envgroup_list_installed_command_assert: "yum group list installed -v |
        awk '/Installed Environment Groups:/{a=1}/Installed Groups:/{a=0}{if (a==1&&!/:/){print $NF}}' |
        sed 's,(,,;s,),,'"

# Reason for noqa: The command to be executed might contain pipes
    - name: Check if required RHEL 8 environment groups are installed # noqa command-instead-of-shell
      shell: "{{ __sap_preconfigure_fact_yum_envgroup_list_installed_command_assert }}"
      register: __sap_preconfigure_register_yum_envgroup_assert
      changed_when: no
      args:
        warn: false

    - name: Assert that all required RHEL 8 environment groups are installed
      assert:
        that: "'{{ line_item }}' in __sap_preconfigure_register_yum_envgroup_assert.stdout_lines"
        fail_msg: "FAIL: Environment group '{{ line_item }}' is not installed!"
        success_msg: "PASS: Environment group '{{ line_item }}' is installed."
      with_items:
        - "{{ sap_preconfigure_envgroups }}"
      loop_control:
        loop_var: line_item
      ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"

  when:
    - sap_preconfigure_envgroups|d([])
    - ansible_os_family == 'RedHat'
    - ansible_distribution_major_version == '8'

- name: Assert that all required packages are installed
  assert:
    that: "'{{ line_item }}' in ansible_facts.packages"
    fail_msg: "FAIL: Package '{{ line_item }}' is not installed!"
    success_msg: "PASS: Package '{{ line_item }}' is installed."
  with_items:
    - "{{ sap_preconfigure_packages }}"
  loop_control:
    loop_var: line_item
  ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"

- name: Minimum required package version check
  block:
    - name: Assert - Create a list of minimum required package versions to be installed
# How does it work?
# 1 - Print the required package name and version with a prefix "1" followed by a space.
# 2 - In the same output sequence, list all installed versions of this package with a prefix "2" followed by a space.
# 3 - Replace all occurrences of ".el" by ".0.0" so that the sort -V correctly sorts packages with ".el" in its name
# 4 - Sort the list by the name and version.
# 5 - Replace ".0.0" by ".el" again to get back the original names.
# 6 - Store the last installed version of the package in variable latestpkg.
# 7 - Store the last content of column 1 in variable col1, the last content of column 2 in variable col2,
#     and the last number of fields in variable _nf.
# 8 - case 1: If the last number of output fields is greater than 2, it indicates that the package is not installed
#             because the output of "rpm -q" will be similar to "package XXX is not installed".
# 8 - case 2a: If the first column of the last line of the output is "1", it means that the required package is
#              the latest of all required and installed versions of the package, so it means that the package needs
#              to be updated.
# 8 - case 2b: If the first column of the last line of the output is "2", it means that at least of the installed
#              versions the package is equal to or greater than the required package version.
      shell: |
        (echo "1 {{ pkg[0] }}-{{ pkg[1] }}";rpm -q --qf "%{NAME}-%{VERSION}-%{RELEASE}\n" {{ pkg[0] }} |
         awk '{printf ("2 %s\n", $0)}') |
         awk '{gsub ("\\.el", ".0.0"); print}' |
         sort -k 2 -k 1 -V |
         awk '{gsub ("\\.0\\.0", ".el"); col1=$1; col2=$2; _nf=NF}
           $1==2{latestpkg=$2}
           END {
               if (_nf>2) {
                  printf ("Package '\''{{ pkg[0] }}'\'' needs to be installed as {{ pkg[0] }}-{{ pkg[1] }}!\n")
               } else {
                  if (col1==1) {
                     printf ("Package '\''{{ pkg[0] }}'\'' needs to be updated to %s! Currently installed latest version: %s.\n", $2, latestpkg)
                  }
                  if (col1==2) {
                     printf ("Package '\''{{ pkg[0] }}'\'' is already installed as {{ pkg[0] }}-{{ pkg[1] }} or later. Currently installed latest version: %s.\n", latestpkg)
                  }
               }
            }'
      with_list: "{{ __sap_preconfigure_min_pkgs }}"
      loop_control:
        loop_var: pkg
      check_mode: no
      register: __sap_preconfigure_register_minpkglist_assert
      changed_when: no

    - name: Assert that minimum required package versions are installed
# If the output includes the string "is already installed" (case 2b), we have a PASS. Otherwise, it's a FAIL.
      assert:
        that: "'is already installed' in line_item.stdout"
        fail_msg: "FAIL: {{ line_item.stdout }}"
        success_msg: "PASS: {{ line_item.stdout }}"
      with_items: "{{ __sap_preconfigure_register_minpkglist_assert.results }}"
      loop_control:
        loop_var: line_item
        label: ""
      ignore_errors: yes

  when:
    - sap_preconfigure_min_package_check|bool
    - __sap_preconfigure_min_pkgs|d([])

- name: Report if no minimum required package version is defined for this RHEL release
  debug:
    msg: "INFO: No minimum required package version defined (variable __sap_preconfigure_min_pkgs)."
  ignore_errors: yes
  when: not __sap_preconfigure_min_pkgs|d([])

- name: Get info about possible package updates
  command: yum check-update
  register: __sap_preconfigure_register_yum_check_update_assert
  args:
    warn: false
  changed_when: false
  ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"
  when: sap_preconfigure_update

- name: Assert that there are no more possible package updates
  assert:
    that: __sap_preconfigure_register_yum_check_update_assert is success
    fail_msg: "FAIL: System needs to be updated!"
    success_msg: "PASS: There are no more outstanding package updates."
  ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"
  when: sap_preconfigure_update

- name: Report if checking for possible package updates is not requested
  debug:
    msg: "INFO: Not checking for possible package updates (variable sap_preconfigure_update)."
  ignore_errors: yes
  when: not sap_preconfigure_update

- name: "Assert - Set needs-restarting command in case of RHEL 7"
  set_fact:
    __sap_preconfigure_fact_needs_restarting_command_assert: "needs-restarting -r"
  when:
    - ansible_os_family == 'RedHat'
    - ansible_distribution_major_version == '7'

- name: "Assert - Set needs-restarting command in case of RHEL 8 or RHEL 9, except RHEL 8.0"
  set_fact:
    __sap_preconfigure_fact_needs_restarting_command_assert: "yum needs-restarting -r"
  when:
    - ansible_os_family == 'RedHat'
    - (ansible_distribution_major_version == '8' or
         ansible_distribution_major_version == '9'
      )
    - ansible_distribution_version != '8.0'

- name: "Assert - Set customized needs-restarting command in case of RHEL 8.0"
  set_fact:
    __sap_preconfigure_fact_needs_restarting_command_assert: "_IKRNL=$(rpm -q --last kernel | awk 'NR==1{sub(/kernel-/,\"\"); print $1}');
                                                              _CKRNL=$(uname -r); if [ ${_IKRNL} != ${_CKRNL} ]; then exit 1; else exit 0; fi"
  when:
    - ansible_os_family == 'RedHat'
    - ansible_distribution_version == '8.0'

- name: Assert - Display the command for checking a reboot requirement
  debug:
    var: __sap_preconfigure_fact_needs_restarting_command_assert

# Reason for noqa: The command to be executed might contain pipes
- name: Assert - Determine if the system needs to be restarted # noqa command-instead-of-shell
  shell: "{{ __sap_preconfigure_fact_needs_restarting_command_assert }}"
  register: __sap_preconfigure_register_needs_restarting_assert
  changed_when: false
  args:
    warn: false
  check_mode: false
  ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"

- name: Assert that system needs no restart
  assert:
    that: __sap_preconfigure_register_needs_restarting_assert is success
    fail_msg: "FAIL: System needs to be restarted!"
    success_msg: "PASS: System needs no restart."
  ignore_errors: "{{ sap_preconfigure_assert_ignore_errors|d(false) }}"
