---
# Service Restart Playbook
# Restart specific services with proper dependency handling
# Usage: ansible-playbook playbooks/restart_service.yml -e "service_name=plex host_target=atlantis"
# Usage: ansible-playbook playbooks/restart_service.yml -e "service_name=immich-server host_target=atlantis wait_time=30"

- name: Restart Service with Dependency Handling
  hosts: "{{ host_target | default('all') }}"
  gather_facts: yes
  vars:
    service_name: "{{ service_name | mandatory }}"
    force_restart: "{{ force_restart | default(false) }}"

    # Service dependency mapping
    service_dependencies:
      # Media stack dependencies
      plex:
        depends_on: []
        restart_delay: 30
      sonarr:
        depends_on: ["prowlarr"]
        restart_delay: 20
      radarr:
        depends_on: ["prowlarr"]
        restart_delay: 20
      lidarr:
        depends_on: ["prowlarr"]
        restart_delay: 20
      bazarr:
        depends_on: ["sonarr", "radarr"]
        restart_delay: 15
      jellyseerr:
        depends_on: ["plex", "sonarr", "radarr"]
        restart_delay: 25

      # Immich stack
      immich-server:
        depends_on: ["immich-db", "immich-redis"]
        restart_delay: 30
      immich-machine-learning:
        depends_on: ["immich-server"]
        restart_delay: 20

      # Security stack
      vaultwarden:
        depends_on: ["vaultwarden-db"]
        restart_delay: 25

      # Monitoring stack
      grafana:
        depends_on: ["prometheus"]
        restart_delay: 20
      prometheus:
        depends_on: []
        restart_delay: 30

  tasks:
    - name: Validate required variables
      fail:
        msg: "service_name is required. Use -e 'service_name=SERVICE_NAME'"
      when: service_name is not defined or service_name == ""

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

    - name: Check if service exists
      shell: 'docker ps -a --filter "name={{ service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
      register: service_exists
      changed_when: false

    - name: Fail if service doesn't exist
      fail:
        msg: "Service '{{ service_name }}' not found on {{ inventory_hostname }}"
      when: service_exists.stdout == ""

    - name: Get current service status
      shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Status}}{%endraw%}"'
      register: service_status_before
      changed_when: false

    - name: Display pre-restart status
      debug:
        msg: |
          🔄 RESTART REQUEST for {{ service_name }} on {{ inventory_hostname }}
          📊 Current Status: {{ service_status_before.stdout | default('Not running') }}
          ⏱️  Wait Time: {{ wait_time | default(15) }} seconds
          🔗 Dependencies: {{ service_dependencies.get(service_name, {}).get('depends_on', []) | join(', ') or 'None' }}

    - name: Check dependencies are running
      shell: 'docker ps --filter "name={{ item }}" --format "{%raw%}{{.Names}}{%endraw%}"'
      register: dependency_check
      loop: "{{ service_dependencies.get(service_name, {}).get('depends_on', []) }}"
      when: service_dependencies.get(service_name, {}).get('depends_on', []) | length > 0

    - name: Warn about missing dependencies
      debug:
        msg: "⚠️  Warning: Dependency '{{ item.item }}' is not running"
      loop: "{{ dependency_check.results | default([]) }}"
      when:
        - dependency_check is defined
        - item.stdout == ""

    - name: Create pre-restart backup of logs
      shell: |
        mkdir -p /tmp/service_logs/{{ ansible_date_time.date }}
        docker logs {{ service_name }} --tail 100 > /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_pre_restart.log 2>&1
      ignore_errors: yes

    - name: Stop service gracefully
      shell: docker stop {{ service_name }}
      register: stop_result
      ignore_errors: yes

    - name: Force stop if graceful stop failed
      shell: docker kill {{ service_name }}
      when:
        - stop_result.rc != 0
        - force_restart | bool

    - name: Wait for service to fully stop
      shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
      register: stop_check
      until: stop_check.stdout == ""
      retries: 10
      delay: 2

    - name: Start service
      shell: docker start {{ service_name }}
      register: start_result

    - name: Wait for service to be ready
      pause:
        seconds: "{{ service_dependencies.get(service_name, {}).get('restart_delay', wait_time | default(15)) }}"

    - name: Verify service is running
      shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Status}}{%endraw%}"'
      register: service_status_after
      retries: 5
      delay: 3
      until: "'Up' in service_status_after.stdout"

    - name: Check service health (if health check available)
      shell: 'docker inspect {{ service_name }} --format="{%raw%}{{.State.Health.Status}}{%endraw%}"'
      register: health_check
      ignore_errors: yes
      changed_when: false

    - name: Wait for healthy status
      shell: 'docker inspect {{ service_name }} --format="{%raw%}{{.State.Health.Status}}{%endraw%}"'
      register: health_status
      until: health_status.stdout == "healthy"
      retries: 10
      delay: 5
      when:
        - health_check.rc == 0
        - health_check.stdout != "none"
      ignore_errors: yes

    - name: Create post-restart log snapshot
      shell: |
        docker logs {{ service_name }} --tail 50 > /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_post_restart.log 2>&1
      ignore_errors: yes

    - name: Display restart results
      debug:
        msg: |

          ✅ SERVICE RESTART COMPLETE
          ================================
          🖥️  Host: {{ inventory_hostname }}
          🔧 Service: {{ service_name }}
          📊 Status Before: {{ service_status_before.stdout | default('Not running') }}
          📊 Status After: {{ service_status_after.stdout }}
          {% if health_check.rc == 0 and health_check.stdout != "none" %}
          🏥 Health Status: {{ health_status.stdout | default('Checking...') }}
          {% endif %}
          ⏱️  Restart Duration: {{ service_dependencies.get(service_name, {}).get('restart_delay', wait_time | default(15)) }} seconds
          📝 Logs: /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_*.log

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

    - name: Restart dependent services (if any)
      include_tasks: restart_dependent_services.yml
      vars:
        parent_service: "{{ service_name }}"
      when: restart_dependents | default(false) | bool

  handlers:
    - name: restart_dependent_services
      debug:
        msg: "This would restart services that depend on {{ service_name }}"
