parameters:
- name: componentName
  type: string
  default: $(Build.DefinitionName)
- name: sparseCheckoutDir
  type: string
  default: ''
- name: gpuTarget
  type: string
  default: ''
- name: artifactName
  type: string
  default: drop
- name: os
  type: string
  default: 'ubuntu2204'

steps:
- task: Bash@3
  displayName: Create manifest.json
  condition: always()
  continueOnError: true
  inputs:
    targetType: inline
    script: |
      ${{ iif(or(eq(parameters.os, 'ubuntu2204'), eq(parameters.os, 'ubuntu2404')), 'sudo apt-get install -y jq', '') }}

      # RESOURCES_REPOSITORIES is a runtime variable (not an env var!) that contains quotations and newlines
      # So we need to save it to a file to properly preserve its formatting and contents
      cat <<EOF > resources.repositories
      $(RESOURCES_REPOSITORIES)
      EOF
      echo "Value of resources.repositories:"
      cat resources.repositories

      IS_TAG_BUILD=$(jq 'has("release_repo")' resources.repositories)
      IS_AOMP_BUILD=$(jq 'has("aomp_repo")' resources.repositories)
      IS_MATHLIBS_BUILD=$(jq 'has("libraries_repo")' resources.repositories)

      if [ "$IS_TAG_BUILD" = "true" ] || [ "$IS_AOMP_BUILD" = "true" ] || [ "$IS_MATHLIBS_BUILD" = "true" ]; then
        exclude_keys=("pipelines_repo" "self") # Triggered by a file under ROCm/ROCm
      else
        exclude_keys=("pipelines_repo") # Triggered by a file under a component repo
      fi

      exclude_keys_string=$(printf '"%s", ' "${exclude_keys[@]}")
      exclude_keys_string=${exclude_keys_string%, }

      current=$(jq --argjson exclude "[$exclude_keys_string]" '
        reduce to_entries[] as $entry (
          [];
          if ($exclude | index($entry.key) | not)
          then . + [
            {
              buildNumber: "$(Build.BuildNumber)",
              buildId: "$(Build.BuildId)",
              repoId: $entry.value.id,
              repoName: $entry.value.name,
              repoSparse: "${{ parameters.sparseCheckoutDir }}",
              repoRef: $entry.value.ref,
              repoUrl: $entry.value.url,
              repoVersion: $entry.value.version
            }
          ]
          else .
          end
        )
      ' resources.repositories)

      dependencies=()
      for manifest_file in $(Pipeline.Workspace)/d/**/manifest_*.json; do
        echo "Processing $manifest_file"
        file=$(jq -c '.current | if type=="array" then .[] else . end' "$manifest_file")
        while IFS= read -r line; do
          dependencies+=("$line")
        done <<< "$file"
      done
      dependencies_json=$(printf '%s\n' "${dependencies[@]}" | jq -s '.')

      manifest_filename="manifest_${{ parameters.componentName }}_$(Build.BuildId)_$(Build.BuildNumber)_${{ parameters.os }}_${{ parameters.gpuTarget }}_${{ parameters.artifactName }}"
      echo "##vso[task.setvariable variable=manifest_filename]$manifest_filename"
      manifest_json=$(Build.ArtifactStagingDirectory)/$manifest_filename.json

      jq -n \
        --argjson current "$current" \
        --argjson dependencies "$dependencies_json" \
        '{
          current: $current,
          dependencies: $dependencies
        }' > $manifest_json

      current_rows=$(cat $manifest_json | \
        jq -r '
          .current[] |
          "<tr><td>" + .buildNumber + "</td>" +
          "<td><a href=\"https://dev.azure.com/ROCm-CI/ROCm-CI/_build/results?buildId=" + .buildId + "\">" + .buildId + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "\">" + .repoName + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/tree/" + .repoRef + "/" + .repoSparse + "\">" + .repoSparse + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/tree/" + .repoRef + "\">" + .repoRef + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/commit/" + .repoVersion + "\">" + .repoVersion + "</a></td></tr>"
        ')
      current_rows=$(echo $current_rows)
      echo "##vso[task.setvariable variable=current_rows;]$current_rows"

      dependencies_rows=$(cat $manifest_json | \
        jq -r '
          .dependencies[] |
          "<tr><td>" + .buildNumber + "</td>" +
          "<td><a href=\"https://dev.azure.com/ROCm-CI/ROCm-CI/_build/results?buildId=" + .buildId + "\">" + .buildId + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "\">" + .repoName + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/tree/" + .repoRef + "/" + .repoSparse + "\">" + .repoSparse + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/tree/" + .repoRef + "\">" + .repoRef + "</a></td>" +
          "<td><a href=\"" + .repoUrl + "/commit/" + .repoVersion + "\">" + .repoVersion + "</a></td></tr>"
        ')
      dependencies_rows=$(echo $dependencies_rows)
      echo "##vso[task.setvariable variable=dependencies_rows;]$dependencies_rows"
- task: Bash@3
  displayName: Print manifest.json
  condition: always()
  continueOnError: true
  inputs:
    targetType: inline
    script: |
      cat $(Build.ArtifactStagingDirectory)/$(manifest_filename).json
- task: Bash@3
  displayName: Create manifest.html
  condition: always()
  continueOnError: true
  inputs:
    targetType: inline
    script: |
      manifest_html="$(Build.ArtifactStagingDirectory)/$(manifest_filename).html"
      cat <<EOF > $manifest_html
      <html>
      <h1>$(manifest_filename)</h1>
      <h2>Current</h2>
      <table border="1">
      <tr>
        <th>Build Number</th>
        <th>Build ID</th>
        <th>Repo Name</th>
        <th>Repo Sparse</th>
        <th>Repo Ref</th>
        <th>Repo Version</th>
      </tr>
      $(current_rows)
      </table>
      <h2>Dependencies</h2>
      <table border="1">
      <tr>
        <th>Build Number</th>
        <th>Build ID</th>
        <th>Repo Name</th>
        <th>Repo Sparse</th>
        <th>Repo Ref</th>
        <th>Repo Version</th>
      </tr>
      $(dependencies_rows)
      </table>
      </html>
      EOF

      sed -i -e 's|</tr> <tr>|</tr>\n<tr>|g' \
        -e 's|</td><td>|</td>\n  <td>|g' \
        -e 's|<tr><td>|<tr>\n  <td>|g' \
        -e 's|</td></tr>|</td>\n</tr>|g' $manifest_html

      cat $manifest_html
- task: PublishHtmlReport@1
  displayName: Publish manifest.html
  condition: always()
  continueOnError: true
  inputs:
    tabName: Manifest
    reportDir: $(Build.ArtifactStagingDirectory)/$(manifest_filename).html
- task: Bash@3
  displayName: Save manifest artifact file name
  condition: always()
  continueOnError: true
  inputs:
    workingDirectory: $(Pipeline.Workspace)
    targetType: inline
    script: |
      echo "$(manifest_filename).html" >> pipelineArtifacts.txt
      echo "$(manifest_filename).json" >> pipelineArtifacts.txt
