---
- name: Post-deploy validation for Windows/RDP AWatch-rus
  hosts: aw_windows
  gather_facts: false

  vars:
    aw_windows_deploy_root: "C:\\Program Files\\AWatch-rus"
    aw_windows_state_root: "C:\\ProgramData\\AWatch-rus"
    aw_windows_validation_remote_path: "{{ aw_windows_state_root }}\\aw_validate_ansible.json"
    aw_windows_validation_local_dir: "/tmp/aw-rus-validation-{{ lookup('env','USER') | default('ansible', true) }}"
    aw_windows_server_scheme: "http"
    aw_windows_server_port: 5600
    aw_windows_fail_on_validation_error: true
    aw_windows_launch_task_pattern: "ActivityWatch Launch *"
    aw_windows_recovery_task_name: "ActivityWatch Recovery"
    aw_windows_force_task_restart: true
    aw_windows_api_smoke_check_enabled: true
    aw_windows_api_smoke_check_bucket: ""
    aw_windows_api_smoke_check_limit: 10
    aw_windows_api_smoke_check_wait_seconds: 20

  tasks:
    - name: Вычислить inventory host AW server по умолчанию
      ansible.builtin.set_fact:
        aw_server_inventory_host_effective: "{{ (groups['aw_server'] | default([]) | first) | default('', true) }}"

    - name: Вычислить effective host для AW server
      ansible.builtin.set_fact:
        aw_windows_server_host_effective: >-
          {{
            aw_windows_server_host
            | default(
                (
                  hostvars[aw_server_inventory_host_effective].ansible_host
                  | default(aw_server_inventory_host_effective, true)
                )
                if (aw_server_inventory_host_effective | length) > 0
                else '',
                true
              )
          }}

    - name: Вычислить effective каталог health validation на AW server
      ansible.builtin.set_fact:
        aw_windows_health_validation_dir_effective: >-
          {{
            (
              hostvars[aw_server_inventory_host_effective].aw_rus_health_validation_dir
              | default('/var/lib/activitywatch/health/windows-validation', true)
            )
            if (aw_server_inventory_host_effective | length) > 0
            else ''
          }}

    - name: Аккуратно запустить ActivityWatch recovery и launch tasks, если они не в Running
      when: aw_windows_force_task_restart | bool
      ansible.windows.win_powershell:
        script: |
          $ErrorActionPreference = 'Stop'
          $recovery = Get-ScheduledTask -TaskName "{{ aw_windows_recovery_task_name }}" -ErrorAction SilentlyContinue
          if ($recovery -and $recovery.State -notin @('Running', 'Queued')) {
            Start-ScheduledTask -TaskName "{{ aw_windows_recovery_task_name }}"
          }
          Get-ScheduledTask |
            Where-Object TaskName -like "{{ aw_windows_launch_task_pattern }}" |
            Where-Object State -notin @('Running', 'Queued') |
            ForEach-Object { Start-ScheduledTask -TaskName $_.TaskName }

    - name: Получить Windows hostname для AW smoke-check bucket
      when: aw_windows_api_smoke_check_enabled | bool
      ansible.windows.win_command: powershell.exe -NoProfile -Command "$env:COMPUTERNAME"
      register: aw_windows_hostname_result
      changed_when: false

    - name: Вычислить AW AFK smoke-check bucket
      when: aw_windows_api_smoke_check_enabled | bool
      ansible.builtin.set_fact:
        aw_windows_api_smoke_check_bucket_effective: >-
          {{
            aw_windows_api_smoke_check_bucket
            if (aw_windows_api_smoke_check_bucket | default('') | string | length) > 0
            else 'aw-worktime-sessions_' ~ (aw_windows_hostname_result.stdout | trim)
          }}

    - name: Дождаться короткого окна стабилизации после перезапуска задач
      when: aw_windows_api_smoke_check_enabled | bool
      ansible.builtin.pause:
        seconds: "{{ aw_windows_api_smoke_check_wait_seconds | int }}"

    - name: Дождаться свежих worktime-событий на AW server
      when: aw_windows_api_smoke_check_enabled | bool
      delegate_to: localhost
      ansible.builtin.uri:
        url: "{{ aw_windows_server_scheme }}://{{ aw_windows_server_host_effective }}:{{ aw_windows_server_port }}/api/0/buckets/{{ aw_windows_api_smoke_check_bucket_effective }}/events?limit={{ aw_windows_api_smoke_check_limit }}"
        method: GET
        status_code: 200
        return_content: true
      register: aw_windows_api_smoke
      until: >
        aw_windows_api_smoke.status == 200 and
        (aw_windows_api_smoke.json | length) > 0 and
        (
          aw_windows_api_smoke.json
          | selectattr('data.source', 'equalto', 'worktime-session-collector')
          | list
          | length
        ) > 0
      retries: 10
      delay: 6

    - name: Выполнить валидацию и сохранить отчёт на целевом Windows host
      ansible.windows.win_powershell:
        script: |
          $ErrorActionPreference = 'Stop'
          $report = & "{{ aw_windows_deploy_root }}\windows\validate-deployment.ps1" `
            -ConfigPath "{{ aw_windows_state_root }}\deployment-config.json"
          $report | ConvertTo-Json -Depth 12 | Out-File -FilePath "{{ aw_windows_validation_remote_path }}" -Encoding utf8
          if ({{ '$true' if (aw_windows_fail_on_validation_error | bool) else '$false' }} -and -not [bool]$report.overallOk) {
            throw "ActivityWatch validation failed. Report: {{ aw_windows_validation_remote_path }}"
          }

    - name: Создать локальный каталог для validation reports
      ansible.builtin.file:
        path: "{{ aw_windows_validation_local_dir }}"
        state: directory
        mode: "0755"
      delegate_to: localhost

    - name: Забрать validation report
      ansible.builtin.fetch:
        src: "{{ aw_windows_validation_remote_path }}"
        dest: "{{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}-aw_validate_ansible.json"
        flat: true

    - name: Убедиться, что каталог Windows validation существует на AW server
      when:
        - aw_server_inventory_host_effective | length > 0
        - aw_windows_health_validation_dir_effective | length > 0
      ansible.builtin.file:
        path: "{{ aw_windows_health_validation_dir_effective }}"
        state: directory
        mode: "0755"
      delegate_to: "{{ aw_server_inventory_host_effective }}"

    - name: Опубликовать validation report на AW server для aw-rus-healthd
      when:
        - aw_server_inventory_host_effective | length > 0
        - aw_windows_health_validation_dir_effective | length > 0
      ansible.builtin.copy:
        src: "{{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}-aw_validate_ansible.json"
        dest: "{{ aw_windows_health_validation_dir_effective }}/{{ inventory_hostname }}-aw_validate_ansible.json"
        mode: "0644"
      delegate_to: "{{ aw_server_inventory_host_effective }}"

    - name: Показать путь к отчёту
      ansible.builtin.debug:
        msg:
          - "Validation OK on {{ inventory_hostname }}."
          - "Report: {{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}-aw_validate_ansible.json"
