---
- name: Comprehensive Linux System Audit and Inventory
  hosts: all
  become: no
  gather_facts: yes
  strategy: free
  vars:
    audit_script_name: "comprehensive_discovery.sh"
    audit_script_path: "migration_scripts/discovery/comprehensive_discovery.sh"
    local_results_dir: "./audit_results"
    remote_script_path: "/tmp/{{ audit_script_name }}"
    ansible_ssh_retries: 5
    ansible_timeout: 60
    audit_timeout: 1800  # 30 minutes for audit execution
    audit_poll_interval: 60  # Check every 60 seconds

  pre_tasks:
    - name: Validate host connectivity
      ansible.builtin.ping:
      register: ping_result
      retries: 3
      delay: 5
      until: ping_result is success

    - name: Check available disk space
      ansible.builtin.command: df -h /tmp
      register: disk_space
      changed_when: false

    - name: Display disk space information
      ansible.builtin.debug:
        msg: "Available disk space on {{ inventory_hostname }}: {{ disk_space.stdout }}"

  tasks:
    - name: Create local results directory
      delegate_to: localhost
      become: no
      run_once: true
      ansible.builtin.file:
        path: "{{ local_results_dir }}"
        state: directory
        mode: '0755'

    - name: Install required packages with retry logic
      become: yes
      ansible.builtin.package:
        name:
          - net-tools
          - lsof
          - nmap
          - curl
          - wget
          - tree
          - ethtool
          - jq
        state: present
      register: package_install
      retries: 5
      delay: 20
      until: package_install is success
      ignore_errors: yes # Continue if some packages fail (e.g., not in repos)

    - name: Display package installation results
      ansible.builtin.debug:
        msg: "Package installation {{ 'succeeded' if package_install is success else 'had issues' }} on {{ inventory_hostname }}"

    - name: Ensure /tmp has correct permissions
      become: yes
      ansible.builtin.file:
        path: /tmp
        mode: '1777'
        state: directory

    - name: Copy audit script to remote host
      become: yes
      ansible.builtin.copy:
        src: "{{ audit_script_path }}"
        dest: "{{ remote_script_path }}"
        mode: '0755'
        backup: yes
      register: script_copy

    - name: Verify script copy
      ansible.builtin.stat:
        path: "{{ remote_script_path }}"
      register: script_stat

    - name: Display script information
      ansible.builtin.debug:
        msg: "Audit script copied to {{ inventory_hostname }}: {{ script_stat.stat.size }} bytes"

    - name: Run system audit script with enhanced timeout
      become: yes
      ansible.builtin.command: "bash {{ remote_script_path }}"
      args:
        chdir: /tmp
      register: audit_output
      async: "{{ audit_timeout }}"
      poll: "{{ audit_poll_interval }}"
      retries: 2
      delay: 30
      until: audit_output is success

    - name: Display audit execution status
      ansible.builtin.debug:
        msg: "Audit execution on {{ inventory_hostname }}: {{ 'completed' if audit_output is success else 'failed or timed out' }}"

    - name: Find the audit results archive
      ansible.builtin.find:
        paths: /tmp
        patterns: "system_audit_*.tar.gz"
        file_type: file
      register: audit_archives
      changed_when: false
      retries: 5
      delay: 30
      until: audit_archives.files | length > 0

    - name: Set audit archive fact
      ansible.builtin.set_fact:
        audit_archive_path: "{{ (audit_archives.files | sort(attribute='mtime', reverse=true) | first).path }}"
      when: audit_archives.files | length > 0

    - name: Create local host directory
      delegate_to: localhost
      become: no
      ansible.builtin.file:
        path: "{{ local_results_dir }}/{{ inventory_hostname }}"
        state: directory
        mode: '0755'
      when: audit_archive_path is defined

    - name: Fetch audit results archive with retry
      ansible.builtin.fetch:
        src: "{{ audit_archive_path }}"
        dest: "{{ local_results_dir }}/{{ inventory_hostname }}/"
        flat: yes
      when: audit_archive_path is defined
      register: fetch_result
      retries: 5
      delay: 30
      until: fetch_result is success
      failed_when: "fetch_result is failed and 'did not find' not in (fetch_result.msg | default(''))"

    - name: Extract compressed results locally
      delegate_to: localhost
      become: no
      ansible.builtin.unarchive:
        src: "{{ fetch_result.dest }}"
        dest: "{{ local_results_dir }}/{{ inventory_hostname }}/"
        remote_src: yes
      when: fetch_result.changed

    - name: Clean up remote audit files
      become: yes
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      loop:
        - "{{ remote_script_path }}"
        - "{{ audit_archive_path }}"
        - "{{ audit_archive_path | regex_replace('.tar.gz$') }}"
      when:
        - cleanup_remote | default(false)
        - audit_archive_path is defined
      ignore_errors: yes # Don't fail if cleanup fails

  post_tasks:
    - name: Generate audit completion summary
      delegate_to: localhost
      become: no
      run_once: true
      ansible.builtin.debug:
        msg: |
          ========================================
          COMPREHENSIVE DISCOVERY COMPLETE
          ========================================
          Total hosts processed: {{ ansible_play_hosts_all | length }}
          Results are extracted in: {{ local_results_dir }}/<hostname>/
          Review the detailed logs and discovery files there.
          ========================================