# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

- name:                                "1.4 Packages: - Import package list"
  ansible.builtin.include_vars:        os-packages.yaml

- name:                                "1.4 Packages: - Installing packages for tier"
  ansible.builtin.debug:
    msg:                               "Installing packages for tier {{ tier }} on {{ distribution_id }}"

# Analyse the package list for this distribution selecting only those
# packages assigned to the active tier or 'all'.
- name:                                "1.4 Packages: - Determine packages appropriate for tier on: {{ distribution_id }}"
  ansible.builtin.set_fact:
    packages_for_tier:                 "{{ packages[distribution_id] |
                                          selectattr('tier', 'in', ['all', tier]) |
                                          selectattr('node_tier', 'in', ['all', node_tier]) |
                                          list }}"

# Initialize packages_for_specific_tier with an empty list
- name:                                "1.4 Packages: - Initialize specific tier packages"
  ansible.builtin.set_fact:
    packages_for_specific_tier:        []

# Analyse the package list for this distribution selecting only those
# packages assigned to the active tier or 'all'. This is used for
# distributions that have a specific package list.
- name:                                "1.4 Packages: - Determine packages appropriate for tier on: {{ distribution_full_id }}"
  when:                                packages[distribution_full_id] is defined
  ansible.builtin.set_fact:
    packages_for_specific_tier:        "{{ packages[distribution_full_id] |
                                          selectattr('tier', 'in', ['all', tier]) |
                                          selectattr('node_tier', 'in', ['all', node_tier]) | default([]) |
                                          list }}"

- name:                                "1.4 Packages: - Debug - output packages for a specific tier"
  ansible.builtin.debug:
    msg:
                                       - "Distribution        : {{ distribution_id }}"
                                       - "Distribution Full Id: {{ distribution_full_id }}"
                                       - "Tier                : {{ tier }}"
                                       - "Node Tier           : {{ node_tier }}"
                                       - "Packages            : {{ packages | selectattr(distribution_full_id, 'defined') }}"
                                       - "Available keys      : {{ packages.keys() | list }}"
                                       - "Key exists 1        : {{ distribution_full_id in packages }}"
                                       - "Key exists 2        : {{ packages[distribution_full_id] is defined }}"
                                       - "Packages for {{ distribution_id }} : {{ packages_for_tier }}"
                                       - "Packages for {{ distribution_full_id }} : {{ packages_for_specific_tier }}"
    verbosity:                         2

- name:                                "1.4 Packages: - Update OS packages: {{ distro_name }}"
  block:
    - name:                            "1.4 Packages: - Update OS packages RHEL: {{ distro_name }}"
      when:                            ansible_os_family | upper == "REDHAT"
      ansible.builtin.dnf:
        name:                          "{{ packages_for_tier |
                                           selectattr('state', 'equalto', item.state) |
                                           map(attribute='package') |
                                           list }}"
        state:                         "{{ item.state }}"
        disablerepo:                   "epel*"
        skip_broken:                   true
        nobest:                        true
      register:                        package_result
      loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

    - name:                            "1.4 Packages: - Update OS packages SLES: {{ distro_name }}"
      when:                            ansible_os_family | upper == "SUSE"
      ansible.builtin.package:
        name:                          "{{ packages_for_tier |
                                           selectattr('state', 'equalto', item.state) |
                                           map(attribute='package') |
                                           list }}"
        state:                         "{{ item.state }}"
      environment:
        ZYPP_LOCK_TIMEOUT:             "20"
      register:                        package_result
      loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

  rescue:
    - name:                            "1.4 Packages: - Show result from packages module"
      ansible.builtin.debug:
        var:                           package_result
        verbosity:                     2

    - name:                            "1.4 Packages: - Performing rescue action"
      ansible.builtin.pause:
        seconds:                       60

    - name:                            "1.4 Packages: - Update OS packages: {{ distro_name }} and rescue"
      block:
        - name:                        "1.4 Packages: - Update OS packages RHEL: {{ distro_name }}"
          ansible.builtin.dnf:
            name:                      "{{ packages_for_tier |
                                          selectattr('state', 'equalto', item.state) |
                                          map(attribute='package') |
                                          list }}"
            state:                     "{{ item.state }}"
            disablerepo:              "epel*"
            skip_broken:              true
            nobest:                   true
          register:                    package_result
          loop:
            - { state: 'latest' }  # Update necessary packages
            - { state: 'present' }  # Install required packages
            - { state: 'absent' }   # Then remove packages that we don't want
          when:                        ansible_os_family | upper == "REDHAT"

        - name:                        "1.4 Packages: - Update OS packages SLES: {{ distro_name }}"
          ansible.builtin.package:
            name:                      "{{ packages_for_tier |
                                          selectattr('state', 'equalto', item.state) |
                                          map(attribute='package') |
                                          list }}"
            state:                     "{{ item.state }}"
          environment:
            ZYPP_LOCK_TIMEOUT:         "20"
          register:                    package_result
          loop:
            - { state: 'latest' }  # Update necessary packages
            - { state: 'present' }  # Install required packages
            - { state: 'absent' }   # Then remove packages that we don't want
          when:                        ansible_os_family | upper == "SUSE"

      rescue:
        - name:                        "1.4 Packages: - Print stderr before getting error code"
          ansible.builtin.debug:
            msg:                       "debug statement: {{ package_result }}"

        - name:                        "1.4 Packages: - Error handling for Packages: - Update OS packages: {{ distro_name }}"
          ansible.builtin.debug:
            msg:                       "{{ package_result | try_get_error_code_results(task_tag='update_os_packages') }}"

# Similar pattern for distribution_full_id...
- name:                                "1.4 Packages: - Update OS packages: {{ distribution_full_id }}"
  block:
    - name:                            "1.4 Packages: - Update OS packages RHEL: {{ distribution_full_id }}"
      when:                            ansible_os_family | upper == "REDHAT"
      ansible.builtin.dnf:
        name:                          "{{ packages_for_specific_tier |
                                           selectattr('state', 'equalto', item.state) |
                                           map(attribute='package') |
                                           list }}"
        state:                         "{{ item.state }}"
        disablerepo:                   "epel*"
        skip_broken:                   true
        nobest:                        true
      register:                        package_result
      loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

    - name:                            "1.4 Packages: - Update OS packages SLES: {{ distribution_full_id }}"
      when:                            ansible_os_family | upper == "SUSE"
      ansible.builtin.package:
        name:                          "{{ packages_for_specific_tier |
                                           selectattr('state', 'equalto', item.state) |
                                           map(attribute='package') |
                                           list }}"
        state:                         "{{ item.state }}"
      environment:
        ZYPP_LOCK_TIMEOUT:             "20"
      register:                        package_result
      loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

  rescue:
    - name:                            "1.4 Packages: - Print return value"
      ansible.builtin.debug:
        var:                           package_result

    - name:                            "1.4 Packages: - Performing rescue action"
      ansible.builtin.pause:
        seconds:                       60

    - name:                            "1.4 Packages: - Update OS packages: {{ distribution_full_id }} and rescue"
      block:
        - name:                        "1.4 Packages: - Update OS packages RHEL: {{ distribution_full_id }}"
          when:                        ansible_os_family | upper == "REDHAT"
          ansible.builtin.dnf:
            name:                      "{{ packages_for_specific_tier |
                                          selectattr('state', 'equalto', item.state) |
                                          map(attribute='package') |
                                          list }}"
            state:                     "{{ item.state }}"
            disablerepo:               "epel*"
            skip_broken:               true
            nobest:                    true
          register:                    package_result
          loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

        - name:                        "1.4 Packages: - Update OS packages SLES: {{ distribution_full_id }}"
          when:                        ansible_os_family | upper == "SUSE"
          ansible.builtin.package:
            name:                      "{{ packages_for_specific_tier |
                                          selectattr('state', 'equalto', item.state) |
                                          map(attribute='package') |
                                          list }}"
            state:                     "{{ item.state }}"
          environment:
            ZYPP_LOCK_TIMEOUT:         "20"
          register:                    package_result
          loop:
                                       - { state: 'latest'  }  # Update necessary packages
                                       - { state: 'present' }  # Install required packages
                                       - { state: 'absent'  }  # Then remove packages that we don't want

      rescue:
        - name:                        "1.4 Packages: - Print stderr before getting error code"
          ansible.builtin.debug:
            msg:                       "debug statement: {{ package_result }}"

        - name:                        "1.4 Packages: - Error handling for Packages: - Update OS packages: {{ distribution_full_id }}"
          ansible.builtin.fail:
            msg:                       "{{ package_result | try_get_error_code_results(task_tag='update_os_packages') }}"
