name: artifact-unit-tests
on:
  push:
    branches:
      - main
    paths-ignore:
      - '**.md'
  pull_request:
    paths-ignore:
      - '**.md'

jobs:
  upload:
    name: Upload

    strategy:
      matrix:
        runs-on: [ubuntu-latest, windows-latest, macos-latest]
      fail-fast: false

    runs-on: ${{ matrix.runs-on }}

    steps:
    - name: Checkout
      uses: actions/checkout@v5

    - name: Set Node.js 24.x
      uses: actions/setup-node@v5
      with:
        node-version: 24.x

    # Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
    # without these to just compile the artifacts package
    - name: Install root npm packages
      run: npm ci

    - name: Compile artifact package
      run: |
        npm ci
        npm run tsc
      working-directory: packages/artifact

    - name: Create files that will be uploaded
      run: |
        mkdir artifact-path
        echo -n 'hello from file 1' > artifact-path/first.txt
        echo -n 'hello from file 2' > artifact-path/second.txt

    - name: Upload Artifacts
      uses: actions/github-script@v8
      with:
        script: |
          const {default: artifact} = require('./packages/artifact/lib/artifact')

          const artifactName = 'my-artifact-${{ matrix.runs-on }}'
          console.log('artifactName: ' + artifactName)

          const fileContents = ['artifact-path/first.txt','artifact-path/second.txt']

          const uploadResult = await artifact.uploadArtifact(artifactName, fileContents, './')
          console.log(uploadResult)

          const size = uploadResult.size
          const id = uploadResult.id

          console.log(`Successfully uploaded artifact ${id}`)

          try {
            await artifact.uploadArtifact(artifactName, fileContents, './')
            throw new Error('should have failed second upload')
          } catch (err) {
            console.log('Successfully blocked second artifact upload')
          }
  verify:
    name: Verify and Delete
    runs-on: ubuntu-latest
    needs: [upload]
    steps:
    - name: Checkout
      uses: actions/checkout@v5

    - name: Set Node.js 24.x
      uses: actions/setup-node@v5
      with:
        node-version: 24.x

    # Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
    # without these to just compile the artifacts package
    - name: Install root npm packages
      run: npm ci

    - name: Compile artifact package
      run: |
        npm ci
        npm run tsc
      working-directory: packages/artifact

    - name: List and Download Artifacts
      uses: actions/github-script@v8
      with:
        script: |
          const {default: artifactClient} = require('./packages/artifact/lib/artifact')

          const {readFile} = require('fs/promises')
          const path = require('path')

          const findBy = {
            repositoryOwner: process.env.GITHUB_REPOSITORY.split('/')[0],
            repositoryName: process.env.GITHUB_REPOSITORY.split('/')[1],
            token: '${{ secrets.GITHUB_TOKEN }}',
            workflowRunId: process.env.GITHUB_RUN_ID
          }

          const listResult = await artifactClient.listArtifacts({latest: true, findBy})
          console.log(listResult)

          const artifacts = listResult.artifacts
          const expected = [
            'my-artifact-ubuntu-latest',
            'my-artifact-windows-latest',
            'my-artifact-macos-latest'
          ]

          const foundArtifacts = artifacts.filter(artifact =>
            expected.includes(artifact.name)
          )

          if (foundArtifacts.length !== 3) {
            console.log('Unexpected length of found artifacts', foundArtifacts)
            throw new Error(
              `Expected 3 artifacts but found ${foundArtifacts.length} artifacts.`
            )
          }

          console.log('Successfully listed artifacts that were uploaded')

          const files = [
            {name: 'artifact-path/first.txt', content: 'hello from file 1'},
            {name: 'artifact-path/second.txt', content: 'hello from file 2'}
          ]

          for (const artifact of foundArtifacts) {
            const {downloadPath} = await artifactClient.downloadArtifact(artifact.id, {
              path: artifact.name,
              findBy
            })

            console.log('Downloaded artifact to:', downloadPath)

            for (const file of files) {
              const filepath = path.join(
                process.env.GITHUB_WORKSPACE,
                downloadPath,
                file.name
              )

              console.log('Checking file:', filepath)

              const content = await readFile(filepath, 'utf8')
              if (content.trim() !== file.content.trim()) {
                throw new Error(
                  `Expected file '${file.name}' to contain '${file.content}' but found '${content}'`
                )
              }
            }
          }
    - name: Delete Artifacts
      uses: actions/github-script@v8
      with:
        script: |
          const {default: artifactClient} = require('./packages/artifact/lib/artifact')

          const artifactsToDelete = [
            'my-artifact-ubuntu-latest',
            'my-artifact-windows-latest',
            'my-artifact-macos-latest'
          ]

          for (const artifactName of artifactsToDelete) {
            const {id} = await artifactClient.deleteArtifact(artifactName)
          }

          const {artifacts} = await artifactClient.listArtifacts({latest: true})
          const foundArtifacts = artifacts.filter(artifact =>
            artifactsToDelete.includes(artifact.name)
          )

          if (foundArtifacts.length !== 0) {
            console.log('Unexpected length of found artifacts:', foundArtifacts)
            throw new Error(
              `Expected 0 artifacts but found ${foundArtifacts.length} artifacts.`
            )
          }

