---
# Container Logs Collection Playbook
# Collect logs from multiple containers for troubleshooting
# Usage: ansible-playbook playbooks/container_logs.yml -e "service_name=plex"
# Usage: ansible-playbook playbooks/container_logs.yml -e "service_pattern=immich"
# Usage: ansible-playbook playbooks/container_logs.yml -e "collect_all=true"

- name: Collect Container Logs
  hosts: "{{ host_target | default('all') }}"
  gather_facts: yes
  vars:
    target_service_name: "{{ service_name | default('') }}"
    target_service_pattern: "{{ service_pattern | default('') }}"
    target_collect_all: "{{ collect_all | default(false) }}"
    target_log_lines: "{{ log_lines | default(100) }}"
    target_log_since: "{{ log_since | default('1h') }}"
    output_dir: "/tmp/container_logs/{{ ansible_date_time.date }}"
    target_include_timestamps: "{{ include_timestamps | default(true) }}"
    target_follow_logs: "{{ follow_logs | default(false) }}"

  tasks:
    - name: Validate input parameters
      fail:
        msg: "Specify either service_name, service_pattern, or collect_all=true"
      when:
        - target_service_name == ""
        - target_service_pattern == ""
        - not (target_collect_all | bool)

    - name: Check if Docker is running
      systemd:
        name: docker
      register: docker_status
      failed_when: docker_status.status.ActiveState != "active"

    - name: Create local log directory
      file:
        path: "{{ output_dir }}/{{ inventory_hostname }}"
        state: directory
        mode: '0755'
      delegate_to: localhost

    - name: Create remote log directory
      file:
        path: "{{ output_dir }}/{{ inventory_hostname }}"
        state: directory
        mode: '0755'

    - name: Get specific service container
      shell: 'docker ps -a --filter "name={{ target_service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
      register: specific_container
      when: target_service_name != ""
      changed_when: false

    - name: Get containers matching pattern
      shell: 'docker ps -a --filter "name={{ target_service_pattern }}" --format "{%raw%}{{.Names}}{%endraw%}"'
      register: pattern_containers
      when: target_service_pattern != ""
      changed_when: false

    - name: Get all containers
      shell: 'docker ps -a --format "{%raw%}{{.Names}}{%endraw%}"'
      register: all_containers
      when: target_collect_all | bool
      changed_when: false

    - name: Combine container lists
      set_fact:
        target_containers: >-
          {{
            (specific_container.stdout_lines | default([])) +
            (pattern_containers.stdout_lines | default([])) +
            (all_containers.stdout_lines | default([]) if target_collect_all | bool else [])
          }}

    - name: Display target containers
      debug:
        msg: |
          📦 CONTAINER LOG COLLECTION
          ===========================
          🖥️  Host: {{ inventory_hostname }}
          📋 Target Containers: {{ target_containers | length }}
          {% for container in target_containers %}
          - {{ container }}
          {% endfor %}
          📏 Log Lines: {{ target_log_lines }}
          ⏰ Since: {{ target_log_since }}

    - name: Fail if no containers found
      fail:
        msg: "No containers found matching the criteria"
      when: target_containers | length == 0

    - name: Get container information
      shell: |
        docker inspect {{ item }} --format='
        Container: {{ item }}
        Image: {%raw%}{{.Config.Image}}{%endraw%}
        Status: {%raw%}{{.State.Status}}{%endraw%}
        Started: {%raw%}{{.State.StartedAt}}{%endraw%}
        Restart Count: {%raw%}{{.RestartCount}}{%endraw%}
        Health: {%raw%}{{if .State.Health}}{{.State.Health.Status}}{{else}}No health check{{end}}{%endraw%}
        '
      register: container_info
      loop: "{{ target_containers }}"
      changed_when: false

    - name: Collect container logs
      shell: |
        echo "=== CONTAINER INFO ===" > {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
        docker inspect {{ item }} --format='
        Container: {{ item }}
        Image: {%raw%}{{.Config.Image}}{%endraw%}
        Status: {%raw%}{{.State.Status}}{%endraw%}
        Started: {%raw%}{{.State.StartedAt}}{%endraw%}
        Restart Count: {%raw%}{{.RestartCount}}{%endraw%}
        Health: {%raw%}{{if .State.Health}}{{.State.Health.Status}}{{else}}No health check{{end}}{%endraw%}
        ' >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
        echo "" >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
        echo "=== CONTAINER LOGS ===" >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log
        {% if target_include_timestamps | bool %}
        docker logs {{ item }} --since={{ target_log_since }} --tail={{ target_log_lines }} -t >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log 2>&1
        {% else %}
        docker logs {{ item }} --since={{ target_log_since }} --tail={{ target_log_lines }} >> {{ output_dir }}/{{ inventory_hostname }}/{{ item }}.log 2>&1
        {% endif %}
      loop: "{{ target_containers }}"
      ignore_errors: yes

    - name: Get container resource usage
      shell: 'docker stats {{ target_containers | join(" ") }} --no-stream --format "table {%raw%}{{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}{%endraw%}"'
      register: container_stats
      when: target_containers | length > 0
      ignore_errors: yes

    - name: Save container stats
      copy:
        content: |
          Container Resource Usage - {{ ansible_date_time.iso8601 }}
          Host: {{ inventory_hostname }}

          {{ container_stats.stdout }}
        dest: "{{ output_dir }}/{{ inventory_hostname }}/container_stats.txt"
      when: container_stats.stdout is defined

    - name: Check for error patterns in logs
      shell: |
        echo "=== ERROR ANALYSIS ===" > {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
        echo "Host: {{ inventory_hostname }}" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
        echo "Timestamp: {{ ansible_date_time.iso8601 }}" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
        echo "" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt

        for container in {{ target_containers | join(' ') }}; do
          echo "=== $container ===" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt

          # Count error patterns
          error_count=$(docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(error|exception|failed|fatal|panic)" | wc -l)
          warn_count=$(docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(warn|warning)" | wc -l)

          echo "Errors: $error_count" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
          echo "Warnings: $warn_count" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt

          # Show recent errors
          if [ $error_count -gt 0 ]; then
            echo "Recent Errors:" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
            docker logs $container --since={{ target_log_since }} 2>&1 | grep -i -E "(error|exception|failed|fatal|panic)" | tail -5 >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
          fi
          echo "" >> {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
        done
      when: target_containers | length > 0
      ignore_errors: yes

    - name: Create summary report
      copy:
        content: |
          📊 CONTAINER LOG COLLECTION SUMMARY
          ===================================

          🖥️  Host: {{ inventory_hostname }}
          📅 Collection Time: {{ ansible_date_time.iso8601 }}
          📦 Containers Processed: {{ target_containers | length }}
          📏 Log Lines per Container: {{ target_log_lines }}
          ⏰ Time Range: {{ target_log_since }}

          📋 CONTAINERS:
          {% for container in target_containers %}
          - {{ container }}
          {% endfor %}

          📁 LOG FILES LOCATION:
          {{ output_dir }}/{{ inventory_hostname }}/

          📄 FILES CREATED:
          {% for container in target_containers %}
          - {{ container }}.log
          {% endfor %}
          - container_stats.txt
          - error_summary.txt
          - collection_summary.txt (this file)

          🔍 QUICK ANALYSIS:
          Use these commands to analyze the logs:

          # View error summary
          cat {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt

          # Search for specific patterns
          grep -i "error" {{ output_dir }}/{{ inventory_hostname }}/*.log

          # View container stats
          cat {{ output_dir }}/{{ inventory_hostname }}/container_stats.txt

          # Follow live logs (if needed)
          {% for container in target_containers[:3] %}
          docker logs -f {{ container }}
          {% endfor %}

        dest: "{{ output_dir }}/{{ inventory_hostname }}/collection_summary.txt"

    - name: Display collection results
      debug:
        msg: |

          ✅ LOG COLLECTION COMPLETE
          ==========================
          🖥️  Host: {{ inventory_hostname }}
          📦 Containers: {{ target_containers | length }}
          📁 Location: {{ output_dir }}/{{ inventory_hostname }}/

          📄 Files Created:
          {% for container in target_containers %}
          - {{ container }}.log
          {% endfor %}
          - container_stats.txt
          - error_summary.txt
          - collection_summary.txt

          🔍 Quick Commands:
          # View errors: cat {{ output_dir }}/{{ inventory_hostname }}/error_summary.txt
          # View stats: cat {{ output_dir }}/{{ inventory_hostname }}/container_stats.txt

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

    - name: Archive logs (optional)
      archive:
        path: "{{ output_dir }}/{{ inventory_hostname }}"
        dest: "{{ output_dir }}/{{ inventory_hostname }}_logs_{{ ansible_date_time.epoch }}.tar.gz"
        remove: no
      when: archive_logs | default(false) | bool
      delegate_to: localhost
