---
# Tailscale Update Playbook
#
# Updates Tailscale across all managed hosts using the appropriate method
# for each host type.
#
# Usage:
#   ansible-playbook -i inventory.yml playbooks/tailscale_update.yml
#   ansible-playbook -i inventory.yml playbooks/tailscale_update.yml --tags check
#   ansible-playbook -i inventory.yml playbooks/tailscale_update.yml --tags update
#   ansible-playbook -i inventory.yml playbooks/tailscale_update.yml --limit "pi-5,homelab"
#
# Host types and update methods:
#   apt_tailscale:     apt update && apt install tailscale (Debian/Ubuntu)
#   synology:          Manual via DSM Package Center (report only)
#   truenas-scale:     Manual via TrueNAS Apps UI (Docker container, report only)
#   routers:           Manual via vendor UI (report only)

- name: Tailscale Update — Check Versions
  hosts: tailscale_hosts
  gather_facts: false
  tags: [check, update]

  tasks:
    - name: Get current Tailscale version (apt hosts)
      shell: tailscale version 2>/dev/null | head -1 || echo "NOT_INSTALLED"
      register: ts_version
      changed_when: false
      when: "'apt_tailscale' in group_names"

    - name: Get current Tailscale version (Synology)
      shell: |
        for p in /var/packages/Tailscale/target/bin/tailscale /usr/local/bin/tailscale /var/packages/WireGuard/target/bin/tailscale; do
          [ -x "$p" ] && $p version 2>/dev/null | head -1 && exit 0
        done
        synopkg version Tailscale 2>/dev/null || echo "UNKNOWN"
      register: ts_version_synology
      changed_when: false
      when: "'synology' in group_names"

    - name: Get current Tailscale version (TrueNAS Docker)
      shell: docker ps --filter "name=tailscale" --format "{{ '{{' }}.Image{{ '}}' }}" 2>/dev/null | head -1 || echo "UNKNOWN"
      register: ts_version_truenas
      changed_when: false
      become: true
      when: inventory_hostname == 'truenas-scale'

    - name: Get current Tailscale version (OpenWrt)
      shell: tailscale version 2>/dev/null | head -1 || opkg info tailscale 2>/dev/null | grep Version | awk '{print $2}' || echo "UNKNOWN"
      register: ts_version_router
      changed_when: false
      when: "'routers' in group_names"

    - name: Set unified version fact
      set_fact:
        tailscale_current: >-
          {{ ts_version.stdout | default(
             ts_version_synology.stdout | default(
             ts_version_truenas.stdout | default(
             ts_version_router.stdout | default('UNKNOWN')))) | trim }}

    - name: Display current versions
      debug:
        msg: "{{ inventory_hostname }}: {{ tailscale_current }}"

- name: Tailscale Update — APT Hosts
  hosts: apt_tailscale
  gather_facts: false
  become: true
  tags: [update]

  tasks:
    - name: Check for available update
      shell: apt list --upgradable 2>/dev/null | grep tailscale || echo "UP_TO_DATE"
      register: apt_check
      changed_when: false

    - name: Update Tailscale via apt
      apt:
        name: tailscale
        state: latest
        update_cache: true
        cache_valid_time: 300
      register: apt_update
      when: "'UP_TO_DATE' not in apt_check.stdout"

    - name: Get new version after update
      shell: tailscale version | head -1
      register: ts_new_version
      changed_when: false
      when: apt_update is changed

    - name: Report update result
      debug:
        msg: >-
          {{ inventory_hostname }}:
          {{ 'Updated to ' + ts_new_version.stdout if apt_update is changed
             else 'Already up to date' }}

- name: Tailscale Update — Manual Hosts Report
  hosts: tailscale_manual
  gather_facts: false
  tags: [update]

  tasks:
    - name: Report manual update required
      debug:
        msg: >-
          {{ inventory_hostname }} ({{ tailscale_update_method | default('unknown') }}):
          Current version {{ tailscale_current | default('unknown') }}.
          Update manually via {{ tailscale_update_instructions | default('vendor UI') }}.
