---
# Disk Usage Report Playbook
# Monitor storage usage across all hosts and generate comprehensive reports
# Usage: ansible-playbook playbooks/disk_usage_report.yml
# Usage: ansible-playbook playbooks/disk_usage_report.yml -e "alert_threshold=80"
# Usage: ansible-playbook playbooks/disk_usage_report.yml -e "detailed_analysis=true"

- name: Generate Comprehensive Disk Usage Report
  hosts: "{{ host_target | default('all') }}"
  gather_facts: yes
  vars:
    alert_threshold: "{{ alert_threshold | default(85) }}"
    warning_threshold: "{{ warning_threshold | default(75) }}"
    detailed_analysis: "{{ detailed_analysis | default(false) }}"
    report_dir: "/tmp/disk_reports"
    include_docker_analysis: "{{ include_docker_analysis | default(true) }}"
    top_directories_count: "{{ top_directories_count | default(10) }}"

  tasks:
    - name: Create report directory
      file:
        path: "{{ report_dir }}/{{ ansible_date_time.date }}"
        state: directory
        mode: '0755'
      delegate_to: localhost

    - name: Get basic disk usage
      shell: df -h
      register: disk_usage_basic
      changed_when: false

    - name: Get disk usage percentages
      shell: df --output=source,pcent,avail,target | grep -v "Filesystem"
      register: disk_usage_percent
      changed_when: false

    - name: Identify high usage filesystems
      shell: |
        df --output=source,pcent,target | awk 'NR>1 {gsub(/%/, "", $2); if ($2 >= {{ alert_threshold }}) print $0}'
      register: high_usage_filesystems
      changed_when: false

    - name: Get inode usage
      shell: df -i
      register: inode_usage
      changed_when: false

    - name: Analyze Docker storage usage
      shell: |
        echo "=== DOCKER STORAGE ANALYSIS ==="
        if command -v docker &> /dev/null; then
          echo "Docker System Usage:"
          docker system df 2>/dev/null || echo "Cannot access Docker"
          echo ""

          echo "Container Sizes:"
          docker ps --format "table {{.Names}}\t{{.Size}}" 2>/dev/null || echo "Cannot access Docker containers"
          echo ""

          echo "Image Sizes:"
          docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 2>/dev/null | head -20 || echo "Cannot access Docker images"
          echo ""

          echo "Volume Usage:"
          docker volume ls -q | xargs -I {} sh -c 'echo "Volume: {}"; docker volume inspect {} --format "{{.Mountpoint}}" | xargs du -sh 2>/dev/null || echo "Cannot access volume"' 2>/dev/null || echo "Cannot access Docker volumes"
        else
          echo "Docker not available"
        fi
      register: docker_storage_analysis
      when: include_docker_analysis | bool
      changed_when: false

    - name: Find largest directories
      shell: |
        echo "=== TOP {{ top_directories_count }} LARGEST DIRECTORIES ==="

        # Find largest directories in common locations
        for path in / /var /opt /home /volume1 /volume2; do
          if [ -d "$path" ]; then
            echo "=== $path ==="
            du -h "$path"/* 2>/dev/null | sort -hr | head -{{ top_directories_count }} || echo "Cannot analyze $path"
            echo ""
          fi
        done
      register: largest_directories
      when: detailed_analysis | bool
      changed_when: false

    - name: Analyze log file sizes
      shell: |
        echo "=== LOG FILE ANALYSIS ==="

        # System logs
        echo "System Logs:"
        find /var/log -type f -name "*.log" -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "Cannot access system logs"
        echo ""

        # Docker logs
        echo "Docker Container Logs:"
        if [ -d "/var/lib/docker/containers" ]; then
          find /var/lib/docker/containers -name "*-json.log" -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "Cannot access Docker logs"
        fi
        echo ""

        # Application logs
        echo "Application Logs:"
        find /volume1 /opt -name "*.log" -type f -exec du -h {} \; 2>/dev/null | sort -hr | head -10 || echo "No application logs found"
      register: log_analysis
      when: detailed_analysis | bool
      changed_when: false

    - name: Check for large files
      shell: |
        echo "=== LARGE FILES (>1GB) ==="
        find / -type f -size +1G -exec du -h {} \; 2>/dev/null | sort -hr | head -20 || echo "No large files found or permission denied"
      register: large_files
      when: detailed_analysis | bool
      changed_when: false

    - name: Analyze temporary files
      shell: |
        echo "=== TEMPORARY FILES ANALYSIS ==="

        for temp_dir in /tmp /var/tmp /volume1/tmp; do
          if [ -d "$temp_dir" ]; then
            echo "=== $temp_dir ==="
            du -sh "$temp_dir" 2>/dev/null || echo "Cannot access $temp_dir"
            echo "File count: $(find "$temp_dir" -type f 2>/dev/null | wc -l)"
            echo "Oldest file: $(find "$temp_dir" -type f -printf '%T+ %p\n' 2>/dev/null | sort | head -1 | cut -d' ' -f2- || echo 'None')"
            echo ""
          fi
        done
      register: temp_files_analysis
      changed_when: false

    - name: Generate disk usage alerts
      set_fact:
        disk_alerts: []
        disk_warnings: []

    - name: Process disk usage alerts
      set_fact:
        disk_alerts: "{{ disk_alerts + [item] }}"
      loop: "{{ disk_usage_percent.stdout_lines }}"
      when:
        - item.split()[1] | regex_replace('%', '') | int >= alert_threshold | int
      vars:
        usage_percent: "{{ item.split()[1] | regex_replace('%', '') | int }}"

    - name: Process disk usage warnings
      set_fact:
        disk_warnings: "{{ disk_warnings + [item] }}"
      loop: "{{ disk_usage_percent.stdout_lines }}"
      when:
        - item.split()[1] | regex_replace('%', '') | int >= warning_threshold | int
        - item.split()[1] | regex_replace('%', '') | int < alert_threshold | int

    - name: Create comprehensive report
      copy:
        content: |
          📊 DISK USAGE REPORT - {{ inventory_hostname }}
          =============================================

          📅 Generated: {{ ansible_date_time.iso8601 }}
          🖥️  Host: {{ inventory_hostname }}
          💿 OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
          ⚠️  Alert Threshold: {{ alert_threshold }}%
          ⚡ Warning Threshold: {{ warning_threshold }}%

          🚨 CRITICAL ALERTS (>={{ alert_threshold }}%):
          {% if disk_alerts | length > 0 %}
          {% for alert in disk_alerts %}
          ❌ {{ alert }}
          {% endfor %}
          {% else %}
          ✅ No critical disk usage alerts
          {% endif %}

          ⚠️  WARNINGS (>={{ warning_threshold }}%):
          {% if disk_warnings | length > 0 %}
          {% for warning in disk_warnings %}
          🟡 {{ warning }}
          {% endfor %}
          {% else %}
          ✅ No disk usage warnings
          {% endif %}

          💾 FILESYSTEM USAGE:
          {{ disk_usage_basic.stdout }}

          📁 INODE USAGE:
          {{ inode_usage.stdout }}

          🧹 TEMPORARY FILES:
          {{ temp_files_analysis.stdout }}

          {% if include_docker_analysis and docker_storage_analysis.stdout is defined %}
          🐳 DOCKER STORAGE:
          {{ docker_storage_analysis.stdout }}
          {% endif %}

          {% if detailed_analysis %}
          {% if largest_directories.stdout is defined %}
          📂 LARGEST DIRECTORIES:
          {{ largest_directories.stdout }}
          {% endif %}

          {% if log_analysis.stdout is defined %}
          📝 LOG FILES:
          {{ log_analysis.stdout }}
          {% endif %}

          {% if large_files.stdout is defined %}
          📦 LARGE FILES:
          {{ large_files.stdout }}
          {% endif %}
          {% endif %}

          💡 RECOMMENDATIONS:
          {% if disk_alerts | length > 0 %}
          - 🚨 IMMEDIATE ACTION REQUIRED: Clean up filesystems above {{ alert_threshold }}%
          {% endif %}
          {% if disk_warnings | length > 0 %}
          - ⚠️  Monitor filesystems above {{ warning_threshold }}%
          {% endif %}
          - 🧹 Run cleanup playbook: ansible-playbook playbooks/cleanup_old_backups.yml
          - 🐳 Prune Docker: ansible-playbook playbooks/prune_containers.yml
          - 📝 Rotate logs: ansible-playbook playbooks/log_rotation.yml
          - 🗑️  Clean temp files: find /tmp -type f -mtime +7 -delete

          📊 SUMMARY:
          - Total Filesystems: {{ disk_usage_percent.stdout_lines | length }}
          - Critical Alerts: {{ disk_alerts | length }}
          - Warnings: {{ disk_warnings | length }}
          - Docker Analysis: {{ 'Included' if include_docker_analysis else 'Skipped' }}
          - Detailed Analysis: {{ 'Included' if detailed_analysis else 'Skipped' }}

        dest: "{{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.txt"
      delegate_to: localhost

    - name: Create JSON report for automation
      copy:
        content: |
          {
            "timestamp": "{{ ansible_date_time.iso8601 }}",
            "hostname": "{{ inventory_hostname }}",
            "thresholds": {
              "alert": {{ alert_threshold }},
              "warning": {{ warning_threshold }}
            },
            "alerts": {{ disk_alerts | to_json }},
            "warnings": {{ disk_warnings | to_json }},
            "filesystems": {{ disk_usage_percent.stdout_lines | to_json }},
            "summary": {
              "total_filesystems": {{ disk_usage_percent.stdout_lines | length }},
              "critical_count": {{ disk_alerts | length }},
              "warning_count": {{ disk_warnings | length }},
              "status": "{% if disk_alerts | length > 0 %}CRITICAL{% elif disk_warnings | length > 0 %}WARNING{% else %}OK{% endif %}"
            }
          }
        dest: "{{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.json"
      delegate_to: localhost

    - name: Display summary
      debug:
        msg: |

          📊 DISK USAGE REPORT COMPLETE - {{ inventory_hostname }}
          ================================================

          {% if disk_alerts | length > 0 %}
          🚨 CRITICAL ALERTS: {{ disk_alerts | length }}
          {% for alert in disk_alerts %}
          ❌ {{ alert }}
          {% endfor %}
          {% endif %}

          {% if disk_warnings | length > 0 %}
          ⚠️  WARNINGS: {{ disk_warnings | length }}
          {% for warning in disk_warnings %}
          🟡 {{ warning }}
          {% endfor %}
          {% endif %}

          {% if disk_alerts | length == 0 and disk_warnings | length == 0 %}
          ✅ All filesystems within normal usage levels
          {% endif %}

          📄 Reports saved to:
          - {{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.txt
          - {{ report_dir }}/{{ ansible_date_time.date }}/{{ inventory_hostname }}_disk_report.json

          🔍 Next Steps:
          {% if disk_alerts | length > 0 %}
          - Run cleanup: ansible-playbook playbooks/cleanup_old_backups.yml
          - Prune Docker: ansible-playbook playbooks/prune_containers.yml
          {% endif %}
          - Schedule regular monitoring via cron

          ================================================

    - name: Send alert if critical usage detected
      debug:
        msg: |
          🚨 CRITICAL DISK USAGE ALERT 🚨
          Host: {{ inventory_hostname }}
          Critical filesystems: {{ disk_alerts | length }}
          Immediate action required!
      when:
        - disk_alerts | length > 0
        - send_alerts | default(false) | bool
