---
- name: Prepare for testing
  hosts: "{{ test_hosts }},localhost"
  any_errors_fatal: true
  gather_facts: false

  pre_tasks:

    - name: Set full repo URL from collection_to_test
      ansible.builtin.set_fact:
        repo_name: "{{ repo_url }}{{ collection_to_test }}.git"
      when: inventory_hostname == 'localhost'

    - name: Create temp_group
      ansible.builtin.add_host:
        name: "{{ inventory_hostname }}"
        group: test
      run_once: true
      changed_when: false

    - name: Gather distribution facts
      ansible.builtin.setup:
        gather_subset: 'distribution_major_version'
      when:
        - tower_job_id is defined
        - inventory_hostname != 'localhost'

    - name: Set os_fact
      ansible.builtin.set_fact:
        bb_name: "{{ hostvars[inventory_hostname]['os']['name'] }}{{ hostvars[inventory_hostname]['ansible_distribution_major_version'] }}"
      when:
        - tower_job_id is defined
        - inventory_hostname != 'localhost'

    - name: Gather date_time facts
      ansible.builtin.setup:
        gather_subset: 'date_time'
      when:
        - tower_job_id is defined 
        - inventory_hostname != 'localhost'

    - name: Create directory for report file if not exist
      ansible.builtin.file:
        path: "{{ report_dir }}"
        state: directory
        mode: '0755'
        recurse: true
      delegate_to: "{{ report_host }}"
      failed_when: false
      when:
        - tower_job_id is defined 
        - inventory_hostname == 'localhost'

    - name: Write header to central repo file
      ansible.builtin.lineinfile:
        path: "{{report_dir }}{{ report_file }}"
        regexp: "^Collection"
        line: "Collection,Env,Role,Result,Job_id,Timestamp, State"
        state: present
        create: true
      delegate_to: "{{ report_host }}"

    - name: Set timestamp
      ansible.builtin.set_fact: 
        timestamp: "{{ ansible_date_time.date }} {{ ansible_date_time.time }}"
      when: inventory_hostname != 'localhost'


    - name: Write initial test fail to central repo file
      ansible.builtin.lineinfile:
        path: "{{report_dir }}{{ report_file }}"
        regexp: "^{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}"
        line: "{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}, RUNNING, {{ tower_job_id }}, {{ timestamp }}, 1"
        state: present
        create: true
      changed_when: false
      delegate_to: "{{ report_host }}"
      when:
        - tower_job_id is defined
        - inventory_hostname != 'localhost'

    - name: Find prepare tasks
      local_action:
        module: ansible.builtin.find
        paths: "."
        patterns: 'prep*.yml'
      register: _preps
      when: inventory_hostname == 'localhost'

  tasks:
    - name: Include preparation tasks
      ansible.builtin.include_tasks:
        file: "{{ _prep.path }}"
      loop_control:
        loop_var: _prep
      with_items: "{{ _preps.files | sort(attribute='path') }}"
      when:
        - _preps.files is defined
        - inventory_hostname == 'localhost'

- name: Run the tests
  any_errors_fatal: true
  hosts: "{{ [test_hosts] | flatten | join(',') }},localhost"
  gather_facts: false

  pre_tasks:

    - name: Include vault role
      ansible.builtin.include_role:
        name: "{{ use_vault_role | join('') }}"
      when: use_vault_role is defined

    - name: Find vars file
      ansible.builtin.find:
        paths: "."
        patterns: 'vars*.yml'
      register: _varsfiles
      delegate_to: 'localhost'

    - name: Include vars for testing
      ansible.builtin.include_vars:
        file: "{{ _vars.path }}"
      loop_control:
        loop_var: _vars
      with_items: "{{ _varsfiles.files }}"
      when:
        - _varsfiles.files is defined
        - _varsfiles.matched > 0

    - name: Find test playbooks
      ansible.builtin.find:
        paths: "."
        patterns: 'test*.yml'
      register: _tests
      delegate_to: 'localhost'

  tasks:
    - name: Run as block 
      block:
        - name: Include testcases
          ansible.builtin.include_tasks: "{{ _test_case.path }}"
          loop_control:
            loop_var: _test_case
          with_items: "{{ _tests.files | sort(attribute='path') }}"
          when:
            - _tests.files is defined
            - inventory_hostname != 'localhost'

      rescue:
        - name: Fail the play if error
          ansible.builtin.fail:
            msg: "Error occured"

      always:
        - name: Remove vault role
          ansible.builtin.file:
            path: "roles/{{ use_vault_role | join('') }}"
            state: absent
          changed_when: false
          when:
            - use_vault_role is defined
            - inventory_hostname == 'localhost'

        - name: Remove extra roles
          ansible.builtin.file:
            path: "roles/{{ _extr_role }}"
            state: absent
          changed_when: false
          loop_control: 
            loop_var: _extr_role
          with_items: "{{ extra_roles }}"
          when: inventory_hostname == 'localhost'

        - name: "Write test result to central repo file"
          ansible.builtin.lineinfile:
            path: "{{ report_dir }}{{ report_file }}"
            regexp: "^{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}"
            line: "{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}, FAILED, {{ tower_job_id }}, {{ timestamp }}, 2"
            state: present
          changed_when: false
          delegate_to: "{{ report_host }}"
          when:
            - tower_job_id is defined
            - inventory_hostname != 'localhost'

    - name: "Write test result to central repo file"
      ansible.builtin.lineinfile:
        path: "{{ report_dir }}{{ report_file }}"
        regexp: "^{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}"
        line: "{{ collection_to_test }}, {{ env_version }}, {{ hostvars['localhost']['bb_name'] }}, SUCCESS, {{ tower_job_id }}, {{ timestamp }}, 0"
        state: present
      changed_when: false
      delegate_to: "{{ report_host }}"
      when:
        - tower_job_id is defined
        - inventory_hostname != 'localhost'
