---
# The following variables will be set by the runner of this playbook:
# projects_root: Global location for caching project checkouts and roles and collections
#     should not have trailing slash on end
# local_path: Path within projects_root to use for this project
# project_path: A simple join of projects_root/local_path folders
# scm_url: https://server/repo
# insights_url: Insights service URL (from configuration)
# scm_branch: branch/tag/revision (HEAD if unset)
# scm_clean: true/false
# scm_username: username (only for svn/insights)
# scm_password: password (only for svn/insights)
# scm_accept_hostkey: true/false (only for git, set automatically)
# scm_refspec: a refspec to fetch in addition to obtaining version
# roles_enabled: Value of the global setting to enable roles downloading
# collections_enabled: Value of the global setting to enable collections downloading
# awx_version: Current running version of the awx or tower as a string
# awx_license_type: "open" for AWX; else presume Tower

- hosts: localhost
  gather_facts: false
  connection: local
  name: Update source tree if necessary
  tasks:

    - name: delete project directory before update
      file:
        path: "{{project_path|quote}}"
        state: absent
      tags:
        - delete

    - block:
        - name: update project using git
          git:
            dest: "{{project_path|quote}}"
            repo: "{{scm_url}}"
            version: "{{scm_branch|quote}}"
            refspec: "{{scm_refspec|default(omit)}}"
            force: "{{scm_clean}}"
            accept_hostkey: "{{scm_accept_hostkey|default(omit)}}"
          register: git_result

        - name: Set the git repository version
          set_fact:
            scm_version: "{{ git_result['after'] }}"
          when: "'after' in git_result"
      tags:
        - update_git

    - block:
        - name: update project using svn
          subversion:
            dest: "{{project_path|quote}}"
            repo: "{{scm_url|quote}}"
            revision: "{{scm_branch|quote}}"
            force: "{{scm_clean}}"
            username: "{{scm_username|default(omit)}}"
            password: "{{scm_password|default(omit)}}"
          environment:
            LC_ALL: 'en_US.UTF-8'
          register: svn_result

        - name: Set the svn repository version
          set_fact:
            scm_version: "{{ svn_result['after'] }}"
          when: "'after' in svn_result"

        - name: parse subversion version string properly
          set_fact:
            scm_version: "{{scm_version|regex_replace('^.*Revision: ([0-9]+).*$', '\\1')}}"
      tags:
        - update_svn

    - block:
        - name: Ensure the project directory is present
          file:
            dest: "{{project_path|quote}}"
            state: directory

        - name: Fetch Insights Playbook(s)
          insights:
            insights_url: "{{insights_url}}"
            username: "{{scm_username}}"
            password: "{{scm_password}}"
            project_path: "{{project_path}}"
            awx_license_type: "{{awx_license_type}}"
            awx_version: "{{awx_version}}"
          register: results

        - name: Save Insights Version
          set_fact:
            scm_version: "{{results.version}}"
          when: results is defined
      tags:
        - update_insights

    - block:
        - name: Ensure the project archive directory is present
          file:
            dest: "{{ project_path|quote }}/.archive"
            state: directory

        - name: Get archive from url
          get_url:
            url: "{{ scm_url|quote }}"
            dest: "{{ project_path|quote }}/.archive/"
            url_username: "{{ scm_username|default(omit) }}"
            url_password: "{{ scm_password|default(omit) }}"
            force_basic_auth: true
          register: get_archive

        - name: Unpack archive
          project_archive:
            src: "{{ get_archive.dest }}"
            project_path: "{{ project_path|quote }}"
            force: "{{ scm_clean }}"
          when: get_archive.changed or scm_clean
          register: unarchived

        - name: Find previous archives
          find:
            paths: "{{ project_path|quote }}/.archive/"
            excludes:
              - "{{ get_archive.dest|basename }}"
          when: unarchived.changed
          register: previous_archive

        - name: Remove previous archives
          file:
            path: "{{ item.path }}"
            state: absent
          loop: "{{ previous_archive.files }}"
          when: previous_archive.files|default([])

        - name: Set scm_version to archive sha1 checksum
          set_fact:
            scm_version: "{{ get_archive.checksum_src }}"
      tags:
        - update_archive

    - name: Repository Version
      debug:
        msg: "Repository Version {{ scm_version }}"
      tags:
        - update_git
        - update_svn
        - update_insights
        - update_archive

- hosts: localhost
  gather_facts: false
  connection: local
  name: Install content with ansible-galaxy command if necessary
  vars:
    yaml_exts:
      - {ext: .yml}
      - {ext: .yaml}
  tasks:

    - block:
        - name: detect roles/requirements.(yml/yaml)
          stat:
            path: "{{project_path|quote}}/roles/requirements{{ item.ext }}"
          with_items: "{{ yaml_exts }}"
          register: doesRequirementsExist

        - name: fetch galaxy roles from requirements.(yml/yaml)
          command: >
            ansible-galaxy role install -r {{ item.stat.path }}
            --roles-path {{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_roles
            {{ ' -' + 'v' * ansible_verbosity if ansible_verbosity else '' }}
          args:
            chdir: "{{project_path|quote}}"
          register: galaxy_result
          with_items: "{{ doesRequirementsExist.results }}"
          when: item.stat.exists
          changed_when: "'was installed successfully' in galaxy_result.stdout"
          environment:
            ANSIBLE_FORCE_COLOR: false
            GIT_SSH_COMMAND: "ssh -o StrictHostKeyChecking=no"

      when: roles_enabled|bool
      tags:
        - install_roles

    - block:
        - name: detect collections/requirements.(yml/yaml)
          stat:
            path: "{{project_path|quote}}/collections/requirements{{ item.ext }}"
          with_items: "{{ yaml_exts }}"
          register: doesCollectionRequirementsExist

        - name: fetch galaxy collections from collections/requirements.(yml/yaml)
          command: >
            ansible-galaxy collection install -r {{ item.stat.path }}
            --collections-path {{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_collections
            {{ ' -' + 'v' * ansible_verbosity if ansible_verbosity else '' }}
          args:
            chdir: "{{project_path|quote}}"
          register: galaxy_collection_result
          with_items: "{{ doesCollectionRequirementsExist.results }}"
          when: item.stat.exists
          changed_when: "'Installing ' in galaxy_collection_result.stdout"
          environment:
            ANSIBLE_FORCE_COLOR: false
            ANSIBLE_COLLECTIONS_PATHS: "{{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_collections"
            GIT_SSH_COMMAND: "ssh -o StrictHostKeyChecking=no"

      when:
        - "ansible_version.full is version_compare('2.9', '>=')"
        - collections_enabled|bool
      tags:
        - install_collections
