---
version: '3'

tasks:
  common:
    run: once
    log:
      error: Error updating common repository
      start: Updating common repository
      success: Finished updating common repository
    cmds:
      - task: :upstream:common:reset
      - task: :upstream:common:clone
      - task: :upstream:common:copy
      - task: :upstream:common:merge
      - task: :upstream:common:clean
      - task: :upstream:common:template
      - task: :upstream:common:combine
      - task: :vscode:generate
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
      - task: :git:commit:automated
      - task: :git:push:all
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  commondocs:
    run: once
    log:
      error: Error updating common documents repository
      start: Updating common documents repository
      success: Finished updating common documents repository
    cmds:
      - task: :upstream:commondocs:clone
      - task: :upstream:commondocs:copy
      - task: :upstream:commondocs:clean
      - task: :upstream:commondocs:template
      - task: :vscode:generate
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
      - task: :git:commit:automated
      - task: :git:push:all
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  docs:
    run: once
    todo: Remove the git:commit:automated tasks
    log:
      error: Error updating document repository
      start: Updating document repository
      success: Finished updating document repository
    cmds:
      - task: :upstream:docs:clone
      - task: :upstream:docs:copy
      - task: :upstream:docs:merge
      - task: :upstream:docs:clean
      - task: :upstream:docs:template
      - task: :vscode:generate
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
      - task: :git:commit:automated
      - task: :git:push:all
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  project:
    run: once
    log:
      error: Error updating project repository
      start: Running project update logic
      success: Finished running project update logic
    cmds:
      - task: pull
      - task: :upstream:project:clone
      - task: :upstream:project:copy
      - task: :upstream:project:clean
      - task: :upstream:project:template
      - task: :upstream:project:boilerplate
      - task: :vscode:generate
      - task: :upstream:project:merge:package:overrides
      - task: :common:update:update
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
      - task: :git:commit:automated
      - task: :git:push:all
      - task: :{{if eq .REPOSITORY_SUBTYPE "role"}}ansible:galaxy:import{{else}}donothing{{end}}
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  project:scaffold-only:
    run: once
    log:
      error: Error scaffolding project
      start: Scaffolding project
      success: Finished scaffolding project
    cmds:
      - task: pull
      - task: :upstream:project:clone
      - task: :upstream:project:copy
      - task: :upstream:project:clean
      - task: :upstream:project:template
      - task: :upstream:project:boilerplate
      - task: :vscode:generate
      - task: :upstream:project:merge:package:overrides
      - SKIP_UPLOADING=true task common:update:update
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  pull:
    deps:
      - :install:software:git
    run: once
    log:
      error: Error executing initial `git pull` logic
      start: Determining whether or not to `git pull`
      success: Finished initial `git pull` logic
    cmds:
      - |
        if ([ -f "$HOME/.ssh/known_hosts" ] && [ ! -n "$(grep "^gitlab.com " "$HOME/.ssh/known_hosts")" ]) || [[ "${container:=}" == "docker" ]]; then
          if [ -z "$GITLAB_CI" ]; then
            if [ -d "$HOME/.ssh" ]; then
              ssh-keyscan gitlab.com >> "$HOME/.ssh/known_hosts" 2> /dev/null
            fi
            git config url."https://gitlab.com/".insteadOf git@gitlab.com:
          fi
        fi
      - cmd: if git branch -r | grep origin > /dev/null; then git pull --ff-only; fi
        ignore_error: true
      - cmd: git config --unset url."https://gitlab.com/".insteadOf
        ignore_error: true
    status:
      - '[ ! -d .git ]'

  shared:
    run: once
    log:
      error: Error running shared repository update logic
      start: Running shared repository update logic
      success: Finished running shared repository update logic
    cmds:
      - task: pull
      - task: :upstream:shared:copy
      - task: :upstream:shared:variables
      - task: :upstream:shared:template
      - task: :vscode:generate
      - task: :install:modules:local:lockfiles
      - task: :fix:eslint
      - task: :git:commit:automated
      - task: :git:push:all
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  template:
    run: once
    cmds:
      - task: template:liquidjs
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'

  template:liquidjs:
    deps:
      - :install:modules:local
      - :install:npm:liquidjs
      - :install:software:jq
      - template:liquidjs:python:deps
    todo: Update project when Taskfile.yml gets modified
    vars:
      PYTHON_BREW_NOTICE: In order for this file to be generated, the customPyPiPackageName needs to be specified in the
        blueprint section of package.json and the PyPi package needs to be installed on the system.
    env:
      TMP:
        sh: mktemp
    run: once
    log:
      error: Error encountered while generating files from `liquid` template files
      start: Generating files from `liquid` template files
      success: Successfully generated files from templates
    cmds:
      - mkdir -p local
      - |
        if [[ '{{.REPOSITORY_TYPE}}' == 'python' ]] && [ -f '.config/brew/python.rb.liquid' ]; then
          BINARY_NAME="$(jq -r '.customPyPiPackageName' .variables.json)"
          if [[ "$BINARY_NAME" == 'null' ]] || ! type "$BINARY_NAME" &> /dev/null; then
            echo "{{.PYTHON_BREW_NOTICE}}" > .config/brew/python.rb.liquid
          fi
        fi
      - cp package.json package.json.bak
      - |
        PATH="$PATH:$HOME/.local/bin"
        function handlebars() {
          FILE="$1"
          TMP="$(mktemp)"
          .config/log info 'Generating `'"${FILE//.liquid}"'` from `'"$FILE"'`'
          hbs --data .variables.json --helper ./.config/hbs.cjs "$FILE" --stdout > "$TMP"
          mv "$TMP" "${FILE//.liquid}"
          rm "$FILE"
        }
        while read FILE; do
          cp "$FILE" "${FILE//.hbs}"
        done < <(find . -type f -not \( {{.ADDITIONAL_IGNORE_FOLDERS}} {{.IGNORE_FOLDERS}} \) -prune -name '*.liquid.hbs')
        while read FILE; do
          handlebars "$FILE"
        done < <(find . -type f -not \( {{.ADDITIONAL_IGNORE_FOLDERS}} {{.IGNORE_FOLDERS}} \) -prune -name '*.liquid')
        while read CONFIG_FILE; do
          handlebars "$CONFIG_FILE"
        done < <(find .config -type f -name '*.liquid')
      - |
        function ensureKeywords() {
          if [ ! -f "$1" ]; then echo "{}" > "$1"; fi
          KEYWORDS="$(jq -r '.keywords' "$1")"
          if [[ "$KEYWORDS" == 'null' ]] || [[ "$KEYWORDS" == '' ]]; then
            TMP="$(mktemp)"
            jq -r '.keywords = [] | .' "$1" > "$TMP"
            mv "$TMP" "$1"
          fi
        }
        ensureKeywords package.json.bak
      - jq -s -S --arg blueprint "$(jq -r '.blueprint' package.json.bak)"
        --arg keywords "$(jq '.keywords[]' package.json.bak package.json | jq -s '. | unique')"
        --argjson private "$(jq -r '.private' package.json.bak | sed 's/^null$/true/')"
        --arg version "$(jq -r '.version' package.json.bak | sed 's/^null$/0.0.1/')"
        '.[0] * .[1] | .keywords = ($keywords | fromjson) | .blueprint = ($blueprint | fromjson) | .private = $private | .version = $version | .'
        package.json.bak package.json > "$TMP"
      - mv "$TMP" package.json
      - rm package.json.bak
      - task: template:pyproject

  template:liquidjs:python:deps:
    cmds:
      - task: :install:pipx:poet
    status:
      - '[ "{{.REPOSITORY_TYPE}}" != "python" ]'

  template:pyproject:
    run: once
    cmds:
      - task: :install:gh:fusion
      - task: template:pyproject:config
      - task: template:pyproject:local
      - task: template:pyproject:fix
    status:
      - '[ ! -f pyproject.toml ] || [ "{{.DOCKER_BUILDING}}" == "true" ]'

  template:pyproject:config:
    log:
      error: Encountered error while merging `.config/pyproject.partial.toml` into the regenerated `pyproject.toml`
      start: Merging `.config/pyproject.partial.toml` into `pyproject.toml`
      success: The `pyproject.toml` file was successfully generated from `.config/pyproject.partial.toml`
    cmds:
      - fusion toml pyproject.toml .config/pyproject.partial.toml -o pyproject.next.toml
      - mv pyproject.next.toml pyproject.toml
    status:
      - '[ ! -f .config/pyproject.partial.toml ] || [ ! -f pyproject.toml ]'

  template:pyproject:fix:
    cmds:
      - task: :fix:toml
        vars:
          CLI_ARGS: pyproject.toml
      - task: :fix:prettier
        vars:
          CLI_ARGS: pyproject.toml
    status:
      - '[ -n "$NO_INSTALL_HOMEBREW" ]'

  template:pyproject:local:
    deps:
      - :install:gh:fusion
    vars:
      PYPROJECT_NOTICE: |-
        ##### IMPORTANT DEVELOPER NOTICE #####
        # This `pyproject.toml` file is automatically generated.
        # If you want to make changes that persist then you should
        # add your changes to `./docs/pyproject.partial.toml`.
        # Be sure to include the section's title with your custom
        # entries. You can test the generation of this file by running
        # `bash start.sh && task init`.
    log:
      error: Encountered error while merging `local/pyproject.partial.toml` into the regenerated `pyproject.toml`
      start: Merging `local/pyproject.partial.toml` into `pyproject.toml`
      success: The `pyproject.toml` file was successfully generated from `local/pyproject.partial.toml`
    cmds:
      - fusion toml pyproject.toml local/pyproject.partial.toml -o pyproject.next.toml
      - mv pyproject.next.toml pyproject.toml
      - echo '' >> pyproject.toml
      - echo '{{.PYPROJECT_NOTICE}}' >> pyproject.toml
      - echo '' >> pyproject.toml
    status:
      - '[ ! -f local/pyproject.partial.toml ] || [ ! -f pyproject.toml ]'

  variables:
    deps:
      - :install:software:jq
    env:
      FILE_INPUT:
        sh: if [ -f '{{.INPUT_FILE}}' ]; then echo {{.INPUT_FILE}}; else echo ".variables.json"; fi
      TMP:
        sh: mktemp
    run: once
    log:
      error: Encountered error while injecting `{{.OUTPUT_FILE}}` with variables
      start: Injecting `{{.OUTPUT_FILE}}` with variables
      success: Successfully injected `{{.OUTPUT_FILE}}` with variables
    cmds:
      - |
        if [[ "$(jq '.keywords' package.json)" == 'null' ]]; then
          TMP_KEYWORDS="$(mktemp)"
          jq '.keywords = []' package.json > "$TMP_KEYWORDS"
          mv "$TMP_KEYWORDS" package.json
        fi
      - jq --arg blueprint "$(jq -r '.blueprint' package.json | sed 's/^null$/{}/')"
        --arg version "$(jq -r '.version' package.json | sed 's/^null$/0.0.1/')"
        --arg poetry "$(jq -r '.keywords | join("\", \"")' package.json | sed 's/$/"/' | sed 's/^/"/')"
        --arg encoded "$(jq -r '.blueprint.repository.gitlab' package.json | sed 's/https:\/\/gitlab.com\///' | sed 's/\//%252F/g')"
        -S '. = (. * ($blueprint | fromjson)) | .version = $version | .poetryKeywords = $poetry | .gitlab_encoded_path = $encoded'
        "$FILE_INPUT" > "$TMP"
      - mv "$TMP" {{.OUTPUT_FILE}}
      - |
        if [ '{{.REPOSITORY_TYPE}}' == 'ansible' ] && [ -f meta/main.yml ]; then
          task ansible:update:variables:descriptions
        fi
      - |
        if [ '{{.REPOSITORY_TYPE}}' == 'packer' ]; then
          task packer:update:variables
        fi
    status:
      - '[ "{{.DOCKER_BUILDING}}" == "true" ]'
