- name: test out invalid os version
  test_min_os_version:
  register: invalid_os_version
  ignore_errors: yes

- name: assert test out invalid os version
  assert:
    that:
    - invalid_os_version is failed
    - '"This module cannot run on this OS as it requires a minimum version of 20.0, actual was " in invalid_os_version.msg'

- name: test out become requires without become_user set
  test_all_options:
  register: become_system

- name: assert become requires without become_user set
  assert:
    that:
    - become_system is successful
    - become_system.output == "S-1-5-18"

- set_fact:
    become_test_username: ansible_become_test
    gen_pw: "{{ 'password123!' + lookup('password', '/dev/null chars=ascii_letters,digits length=8') }}"

- name: execute tests and ensure that test user is deleted regardless of success/failure
  block:
  - name: create unprivileged user
    win_user:
      name: "{{ become_test_username }}"
      password: "{{ gen_pw }}"
      update_password: always
      groups: Users
    register: become_test_user_result

  - name: create tempdir for test user
    win_file:
      path: C:\Windows\TEMP\test-dir
      state: directory

  - name: deny delete permissions on new temp dir for test user
    win_acl:
      path: C:\Windows\TEMP\test-dir
      user: '{{ become_test_user_result.sid }}'
      type: '{{ item.type }}'
      rights: '{{ item.rights }}'
    loop:
    - type: allow
      rights: ListDirectory, CreateFiles, CreateDirectories, ReadAttributes, ReadExtendedAttributes, WriteData, WriteAttributes, WriteExtendedAttributes, Synchronize
    - type: deny
      rights: DeleteSubdirectoriesAndFiles, Delete

  - name: ensure current user is not the become user
    win_shell: whoami
    register: whoami_out

  - name: verify output
    assert:
      that:
      - not whoami_out.stdout_lines[0].endswith(become_test_username)

  - name: get become user profile dir so we can clean it up later
    vars: &become_vars
      ansible_become_user: "{{ become_test_username }}"
      ansible_become_password: "{{ gen_pw }}"
      ansible_become_method: runas
      ansible_become: yes
    win_shell: $env:USERPROFILE
    register: profile_dir_out

  - name: ensure profile dir contains test username (eg, if become fails silently, prevent deletion of real user profile)
    assert:
      that:
      - become_test_username in profile_dir_out.stdout_lines[0]

  - name: test out become requires when become_user set
    test_all_options:
    vars: *become_vars
    register: become_system

  - name: assert become requires when become_user set
    assert:
      that:
      - become_system is successful
      - become_system.output == become_test_user_result.sid

  - name: run module with tempdir with no delete access
    win_ping:
    register: temp_deletion_warning
    vars:
      <<: *become_vars
      ansible_remote_tmp: C:\Windows\TEMP\test-dir

  always:
  - name: ensure test user is deleted
    win_user:
      name: "{{ become_test_username }}"
      state: absent

  - name: ensure test user profile is deleted
    # NB: have to work around powershell limitation of long filenames until win_file fixes it
    win_shell: rmdir /S /Q {{ profile_dir_out.stdout_lines[0] }}
    args:
      executable: cmd.exe
    when: become_test_username in profile_dir_out.stdout_lines[0] | default("")

  - name: remove test tempdir
    win_file:
      path: C:\Windows\TEMP\test-dir
      state: absent

- name: get PS events containing module args or envvars created since test start
  raw: |
    $dt=[datetime]::FromFileTime({{ test_host_info.current_time }})
    (Get-WinEvent -LogName Microsoft-Windows-Powershell/Operational |
    ? { $_.TimeCreated -ge $dt -and $_.Message -match "fail_module|hyphen-var" }).Count
  register: ps_log_count

- name: assert no PS events contain module args or envvars
  assert:
    that:
    - ps_log_count.stdout | int == 0

- name: pass through ISO 8601 date strings correctly
  test_datetime_string:
    value: '2040-10-27T14:30:00'
  register: iso8601_date
  failed_when: >-
    iso8601_date.value != '2040-10-27T14:30:00' or
    iso8601_date.value_type != 'System.String'

- name: test builtin modules are imported correctly with ETS definitions
  test_builtin_module_ets:
  register: builtin_module_ets

- name: assert builtin modules are imported correctly with ETS definitions
  assert:
    that:
    - builtin_module_ets is successful
    - builtin_module_ets.count > 0

- name: pass through ISO 8601 date strings correctly with become
  test_datetime_string:
    value: '2040-10-27T14:30:00'
  become: true
  become_method: runas
  become_user: SYSTEM
  register: iso8601_date
  failed_when: >-
    iso8601_date.value != '2040-10-27T14:30:00' or
    iso8601_date.value_type != 'System.String'

- name: pass through ISO 8601 date strings correctly with async
  test_datetime_string:
    value: '2040-10-27T14:30:00'
  register: iso8601_date
  async: 60
  poll: 3
  failed_when: >-
    iso8601_date.value != '2040-10-27T14:30:00' or
    iso8601_date.value_type != 'System.String'
