---
version: '3'

vars:
  META_PATH: meta/main.yml
  REQUIREMENTS_PATH: requirements.yml

tasks:
  collection:
    deps:
      - :install:software:yq
    log:
      error: Failed to auto-populate the `{{.KEY}}` collection
      start: Determining if the `{{.KEY}}` collection should be added to the `{{.REQUIREMENTS_PATH}}`
    cmds:
      - |
        COLLECTIONS="$(yq eval '.collections' '{{.REQUIREMENTS_PATH}}')"
        REFERENCES="$(grep -Ril '{{.KEY}}' ./tasks || true)"
        if [[ ! "$COLLECTIONS" =~ '{{.KEY}}' ]] && [ "$REFERENCES" ]; then
          yq eval -i -P '.collections = .collections + {{.VAL}}' '{{.REQUIREMENTS_PATH}}'
          .config/log success 'Automatically added `{{.VAL}}` to {{.REQUIREMENTS_PATH}}'
        fi
      - task: :fix:yaml:dashes
        vars:
          CLI_ARGS: '{{.REQUIREMENTS_PATH}}'

  collection:force:
    deps:
      - :install:software:yq
    log:
      error: Failed to forcefully auto-populate the `{{.KEY}}` collection
      start: Determining if the `{{.KEY}}` collection should be added to the `{{.REQUIREMENTS_PATH}}` (forcefully)
    cmds:
      - |
        COLLECTIONS="$(yq eval '.collections' '{{.REQUIREMENTS_PATH}}')"
        if [[ ! "$COLLECTIONS" =~ '{{.KEY}}' ]]; then
          yq eval -i -P '.collections = .collections + {{.VAL}}' '{{.REQUIREMENTS_PATH}}'
          .config/log success 'Automatically added `{{.VAL}}` to {{.REQUIREMENTS_PATH}}'
        fi
      - task: :fix:yaml:dashes
        vars:
          CLI_ARGS: '{{.REQUIREMENTS_PATH}}'

  dependencies:
    desc: 'Attempt to automatically populate `{{.META_PATH}}` and `{{.REQUIREMENTS_PATH}}`'
    hide: '{{ne (print .REPOSITORY_TYPE "-" .REPOSITORY_SUBTYPE) "ansible-role"}}'
    summary: |
      # Automatically populate `{{.META_PATH}}` and `{{.REQUIREMENTS_PATH}}`

      A role can sometimes have dependencies that need to be installed prior to being run (e.g. most
      roles in Ansible >2.9 need the `community.general` collection installed). Roles also sometimes
      need other roles to run before they are run (e.g. a task that installs a Node.js package needs
      the Node.js installer to run first). This task will scan for common dependencies by doing a text
      search for a handful of common strings. It will then attempt to automatically populate
      `{{.META_PATH}}` and the `{{.REQUIREMENTS_PATH}}`.

      Items it attempts to auto-populate for:

      * chocolatey.chocolatey
      * community.general
      * community.general.homebrew
      * community.general.gem
      * community.general.npm
      * community.general.snap
    log:
      start: Auto-populating the `{{.META_PATH}}` and `{{.REQUIREMENTS_PATH}}` with common dependencies (when appropriate)
      success: Auto-populated the `{{.META_PATH}}` and `{{.REQUIREMENTS_PATH}}` with common dependencies
    cmds:
      - task: collection
        vars:
          KEY: chocolatey.chocolatey
          VAL: >-
            {"name": "chocolatey.chocolatey", "source": "https://galaxy.ansible.com"}
      - task: collection
        vars:
          KEY: community.crypto
          VAL: >-
            {"name": "community.crypto", "source": "https://galaxy.ansible.com"}
      - task: collection
        vars:
          KEY: community.general
          VAL: >-
            {"name": "community.general", "source": "https://galaxy.ansible.com"}
      - task: collection:force
        vars:
          KEY: google.cloud
          VAL: >-
            {"name": "google.cloud", "source": "https://galaxy.ansible.com"}
      - task: dependency
        vars:
          KEY: community.general.homebrew
          ROLE: professormanhattan.homebrew
          VAL: >-
            {"role": "professormanhattan.homebrew", "when": "ansible_os_family == 'Darwin'"}
      - task: dependency
        vars:
          KEY: community.general.npm
          ROLE: professormanhattan.nodejs
          VAL: >-
            {"role": "professormanhattan.nodejs"}
      - task: dependency
        vars:
          KEY: community.general.gem
          ROLE: professormanhattan.ruby
          VAL: >-
            {"role": "professormanhattan.ruby"}
      - task: dependency
        vars:
          KEY: community.general.snap
          ROLE: professormanhattan.snapd
          VAL: >-
            {"role": "professormanhattan.snapd", "when": "ansible_system == 'Linux'"}
      - task: dependency
        vars:
          KEY: professormanhattan.startmenu
          ROLE: professormanhattan.startmenu
          VAL: >-
            {"role": "professormanhattan.startmenu", "when": "ansible_system == 'Windows'"}
      - task: :ansible:sync:requirements
    sources:
      - '{{.META_PATH}}'
      - '{{.REQUIREMENTS_PATH}}'
      - tasks/**/*.yml

  dependency:
    deps:
      - :install:software:yq
    log:
      error: Failed to auto-populate the `{{.KEY}}` role
      start: Determining if the `{{.KEY}}` role should be added to the `{{.META_PATH}}`
    cmds:
      - |
        DEPENDENCIES="$(yq eval '.dependencies' '{{.META_PATH}}')"
        REFERENCES="$(grep -Ril '{{.KEY}}' ./tasks || true)"
        if [[ ! "$DEPENDENCIES" =~ '{{.ROLE}}' ]] && [ "$REFERENCES" ]; then
          if [[ '{{.GALAXY_NAMESPACE}}.{{.GALAXY_ROLE_NAME}}' != '{{.ROLE}}' ]]; then
            yq eval -i -P '.dependencies = .dependencies + {{.VAL}}' '{{.META_PATH}}'
            .config/log success 'Automatically added `{{.VAL}}` to {{.META_PATH}}'
          fi
        fi
      - task: :fix:yaml:dashes
        vars:
          CLI_ARGS: '{{ .META_PATH }}'
    status:
      - '[[ "$DEPENDENCIES" =~ "{{.ROLE}}" ]] || [ ! "$REFERENCES" ]'

  meta:
    deps:
      - :install:npm:prettier
      - :install:software:jq
      - :install:software:yq
    vars:
      DESCRIPTION:
        sh: yq eval '.galaxy_info.description' '{{.META_PATH}}'
      REFERENCE_LINK: Take a look at an [example meta/main.yml
        file](https://gitlab.com/megabyte-labs/ansible-roles/androidstudio/-/blob/master/{{.META_PATH}}).
    log:
      error: Failed to synchronize `package.json` with `{{.META_PATH}}`
      start: Updating `package.json` blueprint description and slug using values present in `{{.META_PATH}}`
      success: Ensured `package.json` is synchronized with `{{.META_PATH}}`
    cmds:
      - |
        TMP="$(mktemp)"
        jq --arg a '{{.DESCRIPTION}}' --arg b '{{.GALAXY_ROLE_NAME}}' '.blueprint.description = $a | .blueprint.slug = $b' package.json > "$TMP"
        mv "$TMP" package.json
      - '{{.NPX_HANDLE}}prettier --write package.json'
    sources:
      - meta/main.yml
      - package.json
    preconditions:
      - sh: 'test -f {{.META_PATH}}'
        msg: 'The `{{.META_PATH}}` file is missing. A properly filled out `{{.META_PATH}}` file is required for the
          update process. {{.REFERENCE_LINK}}'
      - sh: '[[ "{{.DESCRIPTION}}" != "null" ]]'
        msg: 'The `{{.META_PATH}}` file has a null value for the `galaxy_info.description` key. Ensure the description
          is populated in `{{.META_PATH}}`. {{.REFERENCE_LINK}}'
      - sh: '[[ "{{.GALAXY_ROLE_NAME}}" != "null" ]]'
        msg: 'The `{{.META_PATH}}` file has a null value for the `galaxy_info.role_name` key. Ensure the role name is
          populated in `{{.META_PATH}}`. {{.REFERENCE_LINK}}'
