---
# Staging-Deployment
# Dieses Playbook steuert das Deployment in die Staging-Umgebung

- name: Deployment für STAGING-Umgebung
  hosts: staging
  become: true
  gather_facts: true

  vars:
    # Deployment-Variablen
    project_source: "{{ playbook_dir }}/../.."
    deploy_root: /var/www/michaelschiemer
    deploy_public: "{{ deploy_root }}/public"
    docker_compose_project_path: "{{ deploy_root }}"

  # Vorbereitung des Deployments
  pre_tasks:
    - name: Prüfe Verbindung zum Staging-Server
      ping:
      register: ping_result
      tags: [always, check]

    - name: Zeige Serverinformationen
      debug:
        msg: "Verbunden mit {{ inventory_hostname }} ({{ ansible_host }})"
      tags: [always, check]

  # Rollen für die Basiseinrichtung des Servers
  roles:
    - common
    - docker
    - app
    - nginx
    - php
    - redis

  # Haupttasks für das Deployment
  tasks:
    - name: Synchronisiere Anwendungsdateien
      synchronize:
        src: "{{ project_source }}/"
        dest: "{{ deploy_root }}/"
        delete: yes
        rsync_opts:
          - "--exclude=.git/"
          - "--exclude=node_modules/"
          - "--exclude=vendor/"
          - "--exclude=.env.local"
      tags: [sync, files]

    - name: Wende modulare Deployment-Tasks an
      import_tasks: ../deploy/includes/deploy_common.yml
      tags: [deploy]

  # Nachbereitung nach dem Deployment
  post_tasks:
    - name: Hole Server-IP-Adresse
      shell: hostname -I | awk '{print $1}'
      register: server_ip
      ignore_errors: yes
      tags: [check]

    - name: Hole Nginx-Container-IP (vereinfacht)
      shell: |
        CONTAINER_ID=$(docker ps -q --filter name=michaelschiemer_nginx)
        if [ -n "$CONTAINER_ID" ]; then
          docker inspect $CONTAINER_ID | grep -m 1 '"IPAddress"' | awk -F '"' '{print $4}'
        else
          echo "Container nicht gefunden"
        fi
      register: container_ip
      ignore_errors: yes
      tags: [check]

    - name: Warte kurz bis Docker-Container gestartet sind
      pause:
        seconds: 5
      tags: [check]

    - name: Überprüfe ob curl installiert ist
      shell: which curl || echo "not found"
      register: curl_check
      ignore_errors: yes
      tags: [check]

    - name: Installiere curl falls notwendig
      apt:
        name: curl
        state: present
      when: curl_check.stdout == "not found"
      tags: [check]

    - name: Teste direkten Zugriff auf Nginx-Container via curl
      shell: |
        CONTAINER_IP=$(docker ps -q --filter name=michaelschiemer_nginx | xargs -I{} docker inspect {} --format='{{.NetworkSettings.Networks.frontend.IPAddress}}' 2>/dev/null || echo "nicht verfügbar")
        if [ "$CONTAINER_IP" != "nicht verfügbar" ]; then
          curl -s -I http://$CONTAINER_IP || echo "Verbindung fehlgeschlagen"
        else
          echo "Container-IP nicht verfügbar"
        fi
      register: curl_test
      ignore_errors: yes
      tags: [check]

    - name: Teste lokalen Zugriff auf Port 80
      shell: |
        curl -s --connect-timeout 5 -I http://localhost:80 || curl -s --connect-timeout 5 -I http://127.0.0.1:80 || echo "Lokale Verbindung fehlgeschlagen"
      register: curl_local_test
      ignore_errors: yes
      tags: [check]

    - name: Teste direkten Zugriff auf Nginx-Container
      shell: |
        CONTAINER_ID=$(docker ps -q --filter name=michaelschiemer_nginx)
        if [ -n "$CONTAINER_ID" ]; then
          docker exec $CONTAINER_ID nginx -v || echo "Nginx-Befehl nicht verfügbar"
        else
          echo "Container nicht aktiv"
        fi
      register: nginx_version_test
      ignore_errors: yes
      tags: [check]

    - name: Prüfe Docker-Container-Ports
      shell: docker port michaelschiemer_nginx || echo "Container-Port-Informationen nicht verfügbar"
      register: container_ports
      ignore_errors: yes
      tags: [check]

    - name: Prüfe Anwendungsstatus über Server-IP
      uri:
        url: "http://{{ server_ip.stdout | trim }}/"
        return_content: no
        status_code: 200, 301, 302, 403, 404, 500, 502, 503
        validate_certs: no
        timeout: 10
      register: app_status
      ignore_errors: yes
      delegate_to: localhost
      become: no
      tags: [check]

    - name: Prüfe Anwendungsstatus über konfigurierte Domain (falls IP-Prüfung fehlschlägt)
      uri:
        url: "http://{{ app_domain }}/"
        return_content: no
        status_code: 200, 301, 302, 403, 404, 500, 502, 503
        validate_certs: no
        timeout: 10
      register: app_status
      ignore_errors: yes
      delegate_to: localhost
      become: no
      when: app_status.status is defined and app_status.status|int < 0
      tags: [check]

    - name: Verarbeite app_status zu einem gültigen Wert
      set_fact:
        app_status_code: "{{ app_status.status|default('unbekannt') }}"
      tags: [check]

    - name: Debug app_status
      debug:
        msg: "Aktueller app_status: {{ app_status_code }}"
      tags: [check]

    - name: Prüfe Docker-Container-Status
      shell: docker ps | grep nginx || echo "Kein Nginx-Container gefunden"
      register: nginx_status
      ignore_errors: yes
      tags: [check]

    - name: Ermittle Docker-Netzwerke
      shell: docker network ls
      register: docker_networks
      ignore_errors: yes
      tags: [check]

    - name: Erstelle ein einfaches HTML-Testdokument im public-Verzeichnis
      copy:
        dest: "{{ deploy_root }}/public/index.html"
        content: |
          <!DOCTYPE html>
          <html>
          <head>
              <title>Webserver ist aktiv</title>
              <style>
                  body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
                  h1 { color: #333; }
                  .container { max-width: 800px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
                  .success { color: green; }
                  .info { margin-top: 20px; background: #f8f8f8; padding: 10px; border-radius: 5px; }
              </style>
          </head>
          <body>
              <div class="container">
                  <h1>Webserver ist <span class="success">aktiv</span>!</h1>
                  <p>Diese Seite bestätigt, dass der Nginx-Webserver korrekt läuft.</p>
                  <div class="info">
                      <h3>Server-Informationen:</h3>
                      <p>Datum: {{ ansible_date_time.date | default('nicht verfügbar') }}</p>
                      <p>Server: {{ inventory_hostname }}</p>
                      <p>IP: {{ server_ip.stdout | trim | default('nicht verfügbar') }}</p>
                      <p>Deployment-Zeit: {{ ansible_date_time.iso8601 | default('unbekannt') }}</p>
                  </div>
              </div>
          </body>
          </html>
        mode: '0644'
      tags: [check]

    - name: Erstelle zusätzliche Test-Datei direkt im Webroot
      copy:
        dest: "{{ deploy_root }}/public/test.html"
        content: |
          <!DOCTYPE html>
          <html>
          <head>
              <title>Nginx Test</title>
          </head>
          <body>
              <h1>Nginx Test erfolgreich!</h1>
              <p>Wenn Sie diese Seite sehen, funktioniert der Nginx-Webserver korrekt.</p>
              <p>Server-IP: {{ server_ip.stdout | trim | default('nicht verfügbar') }}</p>
          </body>
          </html>
        mode: '0644'
      tags: [check]

    - name: Hole Container-Informationen für Diagnose
      shell: |
        docker ps | grep michaelschiemer_nginx || echo "Container nicht gefunden"
      register: container_info
      ignore_errors: yes
      tags: [check]

    - name: Prüfe auf offene Ports
      shell: |
        ss -tulpn | grep LISTEN | grep ':80' || echo "Kein Prozess an Port 80 gebunden"
      register: port_check
      ignore_errors: yes
      tags: [check]

    - name: Zeige Anwendungsstatus und Server-Informationen
      debug:
        msg: |
          Anwendungsstatus:
          - Server IP: {{ server_ip.stdout | trim | default('nicht verfügbar') }}
          - Domain: {{ app_domain }}
          - Status: {% if app_status_code == 200 %}Verfügbar (HTTP 200 OK){% elif app_status_code|int > 0 %}Erreichbar aber mit Fehler (HTTP {{ app_status_code }}){% else %}Status konnte nicht ermittelt werden ({{ app_status_code }}){% endif %}

          Docker-Container Status:
          {{ nginx_status.stdout | default('Keine Informationen verfügbar') }}

          Port-Status:
          {{ port_80_check.stdout | default('Keine Port-Informationen verfügbar') }}

          Lokaler Verbindungstest:
          {{ curl_local_test.stdout | default('Keine Testinformationen verfügbar') }}

          Nginx-Version im Container:
          {{ nginx_version_test.stdout | default('Keine Versionsinformationen verfügbar') }}

          Docker-Container sollte auf Port 80 verfügbar sein.

          Lösungsvorschläge bei Verbindungsproblemen:
          - Firewall-Regeln prüfen: sudo ufw status
          - Nginx-Container-Logs prüfen: docker logs michaelschiemer_nginx
          - Stellen Sie sicher, dass kein anderer Prozess Port 80 belegt: ss -tulpn | grep ':80'
          - Container neu starten: cd {{ deploy_root }} && docker-compose -f docker-compose-simple.yml restart nginx
          - Überprüfen Sie den Status: docker-compose -f {{ deploy_root }}/docker-compose-simple.yml ps
      tags: [check]

    - name: Prüfe Nginx-Container Status
      shell: docker ps -a | grep michaelschiemer-nginx
      register: nginx_container_status
      ignore_errors: yes
      tags: [check]

    - name: Prüfe ob Port 80 offen ist
      shell: netstat -tulpn | grep LISTEN | grep ':80'
      register: port_80_status
      ignore_errors: yes
      tags: [check]

    - name: Zeige Container-Status und Port-Informationen
      debug:
        msg: |
          Nginx-Container Status:
          {{ nginx_status.stdout | default('Container nicht gefunden') }}

          Port 80 Status:
          {{ port_80_check.stdout | default('Port 80 scheint nicht zu lauschen') }}

          Server-IP: {{ server_ip.stdout | trim | default('nicht ermittelbar') }}

          Diagnoseinformationen:
          - Überprüfen Sie, ob der Container läuft: docker ps -a
          - Prüfen Sie die Container-Logs: docker logs michaelschiemer_nginx
          - Prüfen Sie die Container-Netzwerkeinstellungen: docker inspect michaelschiemer_nginx
          - Stellen Sie sicher, dass der Host-Port 80 nicht bereits belegt ist
          - Prüfen Sie die Firewall-Einstellungen: sudo ufw status
      tags: [check]
