---
- name: "Windows | Set some variables"
  ansible.builtin.set_fact:
    zabbix_agent_win_download_link: "{{ zabbix_agent_win_download_link is defined | ternary(zabbix_agent_win_download_link, zabbix_agent2_win_download_link) | default(_win_download_link) }}"
    zabbix_agent_win_logfile: "{{ zabbix_agent_win_logfile is defined | ternary(zabbix_agent_win_logfile, zabbix_agent2_win_logfile) | default(_win_logfile) }}"
    zabbix_agent_win_package: "{{ zabbix_agent_win_package is defined | ternary(zabbix_agent_win_package, zabbix_agent2_win_package) | default(_win_package) }}"
    zabbix_agent_win_include: "{{ zabbix_agent_win_include is defined | ternary(zabbix_agent_win_include, zabbix_agent2_win_include) | default(_win_include) }}"

- name: "Windows | Set default architecture"
  ansible.builtin.set_fact:
    windows_arch: 32
  tags:
    - always

- name: "Windows | Override architecture if 64-bit"
  ansible.builtin.set_fact:
    windows_arch: 64
  when:
    - '"64" in ansible_architecture'
  tags:
    - always

- name: "Windows | Set path to zabbix.exe"
  ansible.builtin.set_fact:
    zabbix_win_exe_path: '{{ zabbix_win_install_dir }}\bin\win{{ windows_arch }}\zabbix_agentd.exe'
  tags:
    - always

- name: "Windows | Set variables specific to Zabbix"
  ansible.builtin.set_fact:
    zabbix_win_svc_name: Zabbix Agent
    zabbix_win_exe_path: '{{ zabbix_win_install_dir }}\bin\zabbix_agentd.exe'
    zabbix_win_config_name: "zabbix_agentd.conf"
    zabbix2_win_svc_name: Zabbix Agent 2
    zabbix2_win_exe_path: '{{ zabbix_win_install_dir }}\bin\zabbix_agent2.exe'
    zabbix2_win_config_name: "zabbix_agent2.conf"
  tags:
    - always

- name: "Windows | Check if Zabbix agent is present"
  ansible.windows.win_stat:
    path: "{{ item }}"
  with_items:
    - "{{ zabbix_win_exe_path }}"
    - "{{ zabbix2_win_exe_path }}"
  register: agent_file_info
  tags:
    - always

- name: "Windows | Get Installed Zabbix Agent Version"
  community.windows.win_file_version:
    path: "{{ item.item }}"
  register: zabbix_win_exe_info
  when:
    - item.stat.exists | bool
  with_items: "{{ agent_file_info.results }}"
  tags:
    - always

- name: "Windows | Set facts current zabbix agent installation"
  ansible.builtin.set_fact:
    zabbix_agent_1_binary_exist: true
    zabbix_agent_1_version: zabbix_win_exe_info.results[0].win_file_version.product_version
  when:
    - zabbix_win_exe_info.results[0] is defined
    - zabbix_win_exe_info.results[0].item.stat.exists
    - zabbix_win_exe_info.results[0].item.stat.path == zabbix_win_exe_path
    - zabbix_win_exe_info.results[0].win_file_version.product_version
  tags:
    - always

- name: "Windows | Set facts current zabbix agent installation (agent 2)"
  ansible.builtin.set_fact:
    zabbix_agent_2_binary_exist: true
    zabbix_agent_2_version: zabbix_win_exe_info.results[1].win_file_version.product_version
  when:
    - zabbix_win_exe_info.results[1] is defined
    - zabbix_win_exe_info.results[1].item.stat.exists
    - zabbix_win_exe_info.results[1].item.stat.path == zabbix2_win_exe_path
    - zabbix_win_exe_info.results[1].win_file_version.product_version
  tags:
    - always

- name: "Windows | Check Zabbix service"
  ansible.windows.win_service:
    name: "{{ (item.item.stat.path == zabbix_win_exe_path ) | ternary(zabbix_win_svc_name,zabbix2_win_svc_name) }}"
  register: zabbix_service_info
  when: item.item.stat.exists
  with_items: "{{ zabbix_win_exe_info.results }}"
  tags:
    - always

- name: "Windows | Set facts about current zabbix agent service state"
  ansible.builtin.set_fact:
    zabbix_agent_1_service_exist: true
  when:
    - zabbix_service_info.results[0].exists is defined
    - zabbix_service_info.results[0].exists
    - zabbix_service_info.results[0].display_name == zabbix_win_svc_name
  tags:
    - always

- name: "Windows | Set facts about current zabbix agent service state (agent 2)"
  ansible.builtin.set_fact:
    zabbix_agent_2_service_exist: true
  when:
    - zabbix_service_info.results[1].exists is defined
    - zabbix_service_info.results[1].exists
    - zabbix_service_info.results[1].display_name == zabbix2_win_svc_name
  tags:
    - always

- name: "Windows | Set fact about version change requirement"
  ansible.builtin.set_fact:
    zabbix_agent_version_change: true
  when: >
    (zabbix_agent_1_binary_exist | default(false) and
     zabbix_win_exe_info.results[0].win_file_version.product_version is version(zabbix_version_long, '<>'))
    or
    (zabbix_agent_2_binary_exist | default(false) and
     zabbix_win_exe_info.results[1].win_file_version.product_version is version(zabbix_version_long, '<>'))
    or (zabbix_agent_1_binary_exist | default(false) and zabbix_agent2)
    or (zabbix_agent_2_binary_exist | default(false) and not zabbix_agent2)
  tags:
    - always

##################
# delete section #
##################

- name: "Windows | Stop Zabbix agent v1"
  ansible.windows.win_service:
    name: "{{ zabbix_win_svc_name }}"
    start_mode: auto
    state: stopped
  when:
    - zabbix_agent_version_change | default(false) or zabbix_agent2
    - zabbix_agent_1_service_exist | default(false)

- name: "Windows | Stop Zabbix agent v2"
  ansible.windows.win_service:
    name: "{{ zabbix2_win_svc_name }}"
    start_mode: auto
    state: stopped
  when:
    - zabbix_agent_version_change | default(false) or not zabbix_agent2
    - zabbix_agent_2_service_exist | default(false)

- name: "Windows | Uninstall Zabbix v1"
  ansible.windows.win_command: '"{{ zabbix_win_exe_path }}" --config "{{ zabbix_win_install_dir_conf }}\{{ zabbix_win_config_name }}" --uninstall'
  when:
    - zabbix_agent_version_change | default(false) or zabbix_agent2
    - zabbix_agent_1_service_exist | default(false)

- name: "Windows | Uninstall Zabbix v2"
  ansible.windows.win_command: '"{{ zabbix2_win_exe_path }}" --config "{{ zabbix_win_install_dir_conf }}\{{ zabbix2_win_config_name }}" --uninstall'
  when:
    - zabbix_agent_version_change | default(false) or not zabbix_agent2
    - zabbix_agent_2_service_exist | default(false)

- name: "Windows | Removing Zabbix Directory"
  ansible.windows.win_file:
    path: "{{ zabbix_win_install_dir }}"
    state: absent
  when:
    ((zabbix_agent_version_change | default(false) or zabbix_agent2) and zabbix_agent_1_binary_exist | default(false)) or
    ((zabbix_agent_version_change | default(false) or not zabbix_agent2) and zabbix_agent_2_binary_exist | default(false))

###################
# install section #
###################

- name: "Windows | Create directory structure"
  ansible.windows.win_file:
    path: "{{ item }}"
    state: directory
  with_items:
    - "{{ zabbix_win_install_dir }}"
  tags:
    - install

- name: "Windows | Create directory structure, includes"
  ansible.windows.win_file:
    path: "{{ item }}"
    state: directory
  with_items:
    - "{{ zabbix_agent_win_include }}"
  when:
    - ('.conf' not in zabbix_agent_win_include)
  tags:
    - install

- name: "Windows | Set installation settings (agent 2)"
  ansible.builtin.set_fact:
    zabbix_win_package: "{{ zabbix_win_package | default(_win_package) }}"
    zabbix_win_download_link: "{{ zabbix_win_download_link | default(_win_download_link) }}"
    zabbix_win_exe_path: "{{ zabbix2_win_exe_path }}"
    zabbix_win_config_name: "{{ zabbix2_win_config_name }}"
    zabbix_win_svc_name: "{{ zabbix2_win_svc_name }}"
  when: zabbix_agent2 | bool
  tags:
    - install

- name: "Windows | Check if agent file is already downloaded"
  ansible.windows.win_stat:
    path: '{{ zabbix_win_install_dir }}\{{ zabbix_win_package }}'
  register: file_info
  tags:
    - install

- name: "Windows | Check if agent binaries in place"
  ansible.windows.win_stat:
    path: "{{ zabbix_win_exe_path }}"
  register: zabbix_windows_binaries
  tags:
    - install

- name: "Windows | Download Zabbix Agent Zip file"
  ansible.windows.win_get_url:
    url: "{{ zabbix_win_download_link }}"
    dest: '{{ zabbix_win_install_dir }}\{{ zabbix_win_package }}'
    url_username: "{{ zabbix_download_user | default(omit) }}"
    url_password: "{{ zabbix_download_pass | default(omit) }}"
    force: false
    follow_redirects: all
    proxy_url: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
    validate_certs: "{{ zabbix_download_validate_certs | default(False) | bool }}"
    timeout: "{{ zabbix_download_timeout | default(120) | int }}"
  when:
    - not file_info.stat.exists
    - not zabbix_windows_binaries.stat.exists
  register: zabbix_agent_win_download_zip
  until: zabbix_agent_win_download_zip is succeeded
  throttle: "{{ zabbix_download_throttle | default(5) | int }}"
  tags:
    - install

- name: "Windows | Unzip file"
  community.windows.win_unzip:
    src: '{{ zabbix_win_install_dir }}\{{ zabbix_win_package }}'
    dest: "{{ zabbix_win_install_dir }}"
    creates: "{{ zabbix_win_exe_path }}"
  tags:
    - install

- name: "Windows | Cleanup downloaded Zabbix Agent Zip file"
  ansible.windows.win_file:
    path: '{{ zabbix_win_install_dir }}\{{ zabbix_win_package }}'
    state: absent
  when:
    - zabbix_agent_win_download_zip.changed
  tags:
    - install

- name: "Windows | Copy binary files to expected location"
  ansible.windows.win_copy:
    src: "{{ zabbix_win_install_dir }}\\bin\\{{ item }}"
    dest: "{{ zabbix_win_install_dir_bin }}\\{{ item }}"
    remote_src: yes
  loop:
    - zabbix_agentd.exe
    - zabbix_sender.exe
  when:
    - zabbix_win_install_dir_bin is defined
    - not (zabbix_agent2 | bool)
  tags:
    - install

- name: "Windows | Copy binary files to expected location (zabbix-agent2)"
  ansible.windows.win_copy:
    src: "{{ zabbix_win_install_dir }}\\bin\\{{ item }}"
    dest: "{{ zabbix_win_install_dir_bin }}\\{{ item }}"
    remote_src: yes
  loop:
    - zabbix_agent2.exe
  when:
    - zabbix_win_install_dir_bin is defined
    - zabbix_agent2 | bool
  tags:
    - install

- set_fact:
    zabbix_win_exe_path: "{{ zabbix_win_install_dir_bin }}\\zabbix_agentd.exe"
  when:
    - zabbix_win_install_dir_bin is defined
    - not (zabbix_agent2 | bool)
  tags:
    - install

- set_fact:
    zabbix_win_exe_path: "{{ zabbix_win_install_dir_bin }}\\zabbix_agent2.exe"
  when:
    - zabbix_win_install_dir_bin is defined
    - zabbix_agent2 | bool
  tags:
    - install

- name: "Windows | Check if windows service exist"
  ansible.windows.win_service:
    name: "{{ zabbix_win_svc_name }}"
  register: zabbix_windows_service
  tags:
    - service

- name: "Windows | Register Service"
  ansible.windows.win_command: '"{{ zabbix_win_exe_path }}" --config "{{ zabbix_win_install_dir_conf }}\{{ zabbix_win_config_name }}" --install'
  when: not zabbix_windows_service.exists
  tags:
    - service
