---
- name: ensure test folder is deleted for clean slate
  win_file:
    path: '{{test_win_wait_for_path}}'
    state: absent

- name: ensure test folder exists
  win_file:
    path: '{{test_win_wait_for_path}}'
    state: directory

- name: template out the test server
  win_template:
    src: http-server.ps1
    dest: '{{test_win_wait_for_path}}\http-server.ps1'

# invalid arguments
- name: fail to set port and path
  win_wait_for:
    path: a
    port: 0
  register: fail_port_and_path
  failed_when: fail_port_and_path.msg != 'port and path parameter can not both be passed to win_wait_for'

- name: fail to set exclude_hosts when state isn't drain
  win_wait_for:
    port: 0
    exclude_hosts: a
    state: present
  register: fail_exclude_hosts_not_drained
  failed_when: fail_exclude_hosts_not_drained.msg != 'exclude_hosts should only be with state=drained'

- name: fail to set state drained with path
  win_wait_for:
    path: a
    state: drained
  register: fail_path_drained
  failed_when: fail_path_drained.msg != 'state=drained should only be used for checking a port in the win_wait_for module'

- name: fail to set exclude_hosts with path
  win_wait_for:
    path: a
    exclude_hosts: a
  register: fail_path_exclude_hosts
  failed_when: fail_path_exclude_hosts.msg != 'exclude_hosts should only be with state=drained'

- name: fail to set search_regex with port
  win_wait_for:
    port: 0
    search_regex: a
  register: fail_port_search_regex
  failed_when: fail_port_search_regex.msg != 'regex should by used when checking a string in a file in the win_wait_for module'

- name: fail to set exclude_hosts with port whens tate is not drained
  win_wait_for:
    port: 0
    exclude_hosts: a
    state: present
  register: fail_port_exclude_hosts_not_drained
  failed_when: fail_port_exclude_hosts_not_drained.msg != 'exclude_hosts should only be with state=drained'

# path tests
- name: timeout while waiting for file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: present
    timeout: 5
  register: fail_timeout_file_present
  ignore_errors: True

- name: assert timeout while waiting for file
  assert:
    that:
    - fail_timeout_file_present.msg == 'timeout while waiting for file ' + test_win_wait_for_path + '\\test.txt to be present'
    - fail_timeout_file_present.wait_attempts == 5
    - fail_timeout_file_present.elapsed > 5

- name: wait for file to not exist - non existing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
  register: wait_remove_no_file

- name: assert wait for file to not exist - non existing file
  assert:
    that:
    - wait_remove_no_file.wait_attempts == 1

- name: create file for next test
  win_file:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: touch

- name: run async task to remove file after a timeout
  win_shell: Start-Sleep -Seconds 5; Remove-Item -Path '{{test_win_wait_for_path}}\test.txt' -Force
  async: 30
  poll: 0

- name: wait for file to not exist - existing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
  register: wait_remove_existing_file

- name: assert wait for file to not exist - existing file
  assert:
    that:
    - wait_remove_existing_file.wait_attempts > 1

- name: run async task to create file after a timeout
  win_shell: Start-Sleep -Seconds 5; New-Item -Path '{{test_win_wait_for_path}}\test.txt' -Type File
  async: 30
  poll: 0

- name: wait for file to exist - non existing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: present
  register: wait_new_missing_file

- name: assert wait for file to exist - non existing file
  assert:
    that:
    - wait_new_missing_file.wait_attempts > 1

- name: wait for file to exist - existing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: present
  register: wait_new_existing_file

- name: assert wait for file to exist - existing file
  assert:
    that:
    - wait_new_existing_file.wait_attempts == 1

- name: timeout while waiting for file to not exist
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
    timeout: 5
  register: fail_timeout_file_absent
  ignore_errors: True

- name: assert timeout while waiting for file to not exist
  assert:
    that:
    - fail_timeout_file_absent.msg == 'timeout while waiting for file ' + test_win_wait_for_path + '\\test.txt to be absent'
    - fail_timeout_file_absent.wait_attempts == 5
    - fail_timeout_file_absent.elapsed > 5

- name: run async task to populate file contents
  win_shell: Start-Sleep -Seconds 5; Set-Content -Path '{{test_win_wait_for_path}}\test.txt' -Value 'hello world`r`nfile contents`r`nEnd line'
  async: 30
  poll: 0

- name: wait for file contents to match regex - empty file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: present
    search_regex: file c.*
  register: wait_regex_match_new

- name: assert wait for file contents to match regex - empty file
  assert:
    that:
    - wait_regex_match_new.wait_attempts > 1

- name: wait for file contents to match regex - existing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: present
    search_regex: file c.*
  register: wait_regex_match_existing

- name: assert wait for file contents to match regex - existing file
  assert:
    that:
    - wait_regex_match_existing.wait_attempts == 1

- name: run async task to clear file contents
  win_shell: Start-Sleep -Seconds 5; Set-Content -Path '{{test_win_wait_for_path}}\test.txt' -Value 'hello world`r`nother contents for file`r`nEnd line'
  async: 30
  poll: 0

- name: wait for file content to not match regex
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
    search_regex: file c.*
  register: wait_regex_match_absent_remove

- name: assert wait for file content to not match regex
  assert:
    that:
    - wait_regex_match_absent_remove.wait_attempts > 1

- name: wait for file content to not match regex - existing
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
    search_regex: file c.*
  register: wait_regex_match_absent_existing

- name: assert wait for file content to not match regex
  assert:
    that:
    - wait_regex_match_absent_existing.wait_attempts == 1

- name: remove file to test search_regex works on missing files
  win_file:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent

- name: wait for file content to not match regex - missing file
  win_wait_for:
    path: '{{test_win_wait_for_path}}\test.txt'
    state: absent
    search_regex: file c.*
  register: wait_regex_match_absent_missing

- name: assert wait for file content to not match regex - missing file
  assert:
    that:
    - wait_regex_match_absent_missing.wait_attempts == 1

# port tests
- name: timeout waiting for port to come online
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    timeout: 5
    state: started
  register: fail_timeout_port_online
  ignore_errors: True

- name: assert timeout while waiting for port to come online
  assert:
    that:
    - "fail_timeout_port_online.msg == 'timeout while waiting for 127.0.0.1:' + test_win_wait_for_port|string + ' to start listening'"
    - fail_timeout_port_online.wait_attempts > 1
    - fail_timeout_port_online.elapsed > 5

- name: run async task to start web server
  win_shell: Start-Sleep -Seconds 5; {{test_win_wait_for_path}}\http-server.ps1
  async: 30
  poll: 0

- name: wait for port to come online
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: started
  register: wait_for_port_to_start

- name: assert wait for port to come online
  assert:
    that:
    - wait_for_port_to_start.wait_attempts > 1

- name: start web server
  win_shell: '{{test_win_wait_for_path}}\http-server.ps1'
  async: 30
  poll: 0

- name: wait for port that is already online
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: started
  register: wait_for_port_already_started

- name: assert wait for port that is already online
  assert:
    that:
    - wait_for_port_already_started.wait_attempts == 1

# add a manual wait to make sure the port is truly offline for next test
- name: wait for port to be offline
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: stopped

- name: wait for port that is already offline
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: stopped
  register: wait_for_port_already_stopped

- name: assert wait for port that is already offline
  assert:
    that:
    - wait_for_port_already_stopped.wait_attempts == 1

- name: start web server for offline port test
  win_shell: '{{test_win_wait_for_path}}\http-server.ps1'
  async: 30
  poll: 0

- name: wait for port to go offline
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: stopped
  register: wait_for_port_to_be_stopped

- name: assert wait for port to go offline
  assert:
    that:
    - wait_for_port_to_be_stopped.wait_attempts > 1

- name: wait for offline port to be drained
  win_wait_for:
    port: '{{test_win_wait_for_port}}'
    state: drained
  register: wait_for_drained_port_no_port

- name: assert wait for offline port to be drained
  assert:
    that:
    - wait_for_drained_port_no_port.wait_attempts == 1

- name: clear testing folder
  win_file:
    path: '{{test_win_wait_for_path}}'
    state: absent
