---
- name: Converge idrac_gather_facts for Physical Disk
  hosts: all
  gather_facts: false
  vars:
    hostname: "{{ lookup('env', 'IDRAC_IP') }}"
    username: "{{ lookup('env', 'IDRAC_USER') }}"
    password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
    idrac_port: "{{ lookup('env', 'IDRAC_PORT') }}"
    validate_certs: false
    target:
      - PhysicalDisk
    idrac_gather_facts_uri_method: "GET"
    idrac_gather_facts_uri_headers:
      Accept: "application/json"
      Content-Type: "application/json"
      OData-Version: "4.0"
    idrac_gather_facts_uri_body_format: "json"
    idrac_gather_facts_uri_status_code:
      - 200
      - 400
      - 401
      - 404
      - -1
    idrac_gather_facts_uri_return_content: true
    diff_data: {}
    exclude_keys: []

  tasks:

    - name: Find the system API
      ansible.builtin.include_tasks:
        ../../tests/asserts/_check_system_url.yml

    - name: Get Storage information.
      ansible.builtin.uri: &uri_params
        url: "https://{{ hostname }}{{ api_system }}/Storage"
        validate_certs: "{{ validate_certs }}"
        ca_path: "{{ ca_path | default(omit) }}"
        method: "{{ idrac_gather_facts_uri_method }}"
        user: "{{ username }}"
        password: "{{ password }}"
        headers: "{{ idrac_gather_facts_uri_headers }}"
        body_format: "{{ idrac_gather_facts_uri_body_format }}"
        status_code: "{{ idrac_gather_facts_uri_status_code }}"
        return_content: "{{ idrac_gather_facts_uri_return_content }}"
      register: idrac_gather_facts_controllers_result

    - name: Get all storage controller ids.
      ansible.builtin.set_fact:
        storage_ids_list:
          "{{ idrac_gather_facts_controllers_result.json.Members |
          map('dict2items') | flatten | map(attribute='value') }}"
      when: idrac_gather_facts_controllers_result.json.Members is defined

    - name: Get physical disk information using API.
      ansible.builtin.uri:
        url: "https://{{ hostname }}{{ item }}?$expand=*($levels=1)"
        <<: *uri_params
      loop: "{{ storage_ids_list }}"
      no_log: true
      register: idrac_gather_facts_disk_result
      when: storage_ids_list is defined

    - name: Count the number of drives in drives_result.results
      ansible.builtin.set_fact:
        drives_count: "{{ idrac_gather_facts_disk_result.results |
          map(attribute='json.drives') | list | length }}"
      when: idrac_gather_facts_disk_result.results is defined

    - name: Set Physical Disk facts
      ansible.builtin.set_fact:
        api_response:
          "{{ idrac_gather_facts_disk_result.results |
            selectattr('json', 'defined') | map(attribute='json') |
            selectattr('Drives', 'defined') | map(attribute='Drives') |
            flatten | ansible.utils.remove_keys(target=['@odata.context',
            '@odata.id', '@odata.type', 'Actions', 'Assembly', 'Links',
            'DellDriveSMARTAttributes', 'DellNVMeSMARTAttributes',
            'Operations@odata.count']) }}"
      when: idrac_gather_facts_disk_result.results is defined

    - name: Gather Facts for the Physical Disk component
      ansible.builtin.include_role:
        name: "idrac_gather_facts"

    - name: Assert Physical Disk data
      ansible.builtin.assert:
        that:
          - "((drives_count | length == 0) and (physical_disk | length == 0))"
        fail_msg: "The response from the role does not match"
        success_msg: "The response from the role matches"
      when: drives_count | length == 0

    - name: Check whether output differs
      ansible.builtin.set_fact:
        result_diff: "{{ physical_disk | symmetric_difference(api_response) }}"
      when: drives_count | length > 0

    - name: Assert the differences in List
      ansible.builtin.assert:
        fail_msg: "The response from the role does not match"
        success_msg: "The response from the role matches"
        that:
          - "{{ (result_diff | length) == 0 }}"
      when: drives_count | length > 0
