parameters:
  - name: agentVersion
    type: string
    default: "4.255.0"
  - name: dockerRegistry
    type: string
    default: ""
  - name: imageName
    type: string
    default: "azure-pipelines-agent"
  - name: imageTag
    type: string
    default: ""
  - name: architecture
    type: string
    default: "arm64"

trigger:
  branches:
    include:
      - main
  paths:
    include:
      - "azure-pipelines-agent-arm.yml"

pr: none

pool:
  vmImage: "ubuntu-latest"

variables:
  - name: AGENT_VERSION
    value: ${{ parameters.agentVersion }}
  - name: DOCKER_REGISTRY
    value: ${{ parameters.dockerRegistry }}
  - name: IMAGE_NAME
    value: ${{ parameters.imageName }}
  - name: IMAGE_TAG
    value: ${{ coalesce(parameters.imageTag, parameters.agentVersion) }}
  - name: ARCH
    value: ${{ parameters.architecture }}

stages:
  - stage: Build
    displayName: "Build ARM Agent Image"
    jobs:
      - job: BuildImage
        displayName: "Build and Push Docker Image"
        steps:
          - checkout: self
            fetchDepth: 1

          - task: DockerInstaller@0
            displayName: "Install Docker CLI"
            inputs:
              dockerVersion: "24.0.7"
              releaseType: "stable"

          - bash: |
              sudo apt-get update
              sudo apt-get install -y qemu-user-static binfmt-support
              docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
            displayName: "Set up QEMU for ARM emulation"

          - bash: |
              docker buildx create --use --name arm-builder
              docker buildx inspect --bootstrap
            displayName: "Create Docker Buildx builder"

          - bash: |
              cat <<'DOCKERFILE' > Dockerfile
              FROM arm64v8/ubuntu:22.04

              ARG AGENT_VERSION=${AGENT_VERSION}
              ARG TARGETARCH=arm64

              ENV DEBIAN_FRONTEND=noninteractive
              ENV AGENT_VERSION=${AGENT_VERSION}
              ENV AGENT_DIR=/azp/agent

              RUN apt-get update && apt-get install -y --no-install-recommends \
                  curl \
                  git \
                  jq \
                  libicu70 \
                  libssl3 \
                  locales \
                  locales-all \
                  unzip \
                  wget \
                  zip \
                  && rm -rf /var/lib/apt/lists/*

              RUN locale-gen en_US.UTF-8
              ENV LANG=en_US.UTF-8
              ENV LANGUAGE=en_US:en
              ENV LC_ALL=en_US.UTF-8

              RUN mkdir -p /azp && \
                  cd /azp && \
                  curl -L -o vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz \
                      "https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz" && \
                  tar -xzf vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz && \
                  rm vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz

              COPY start.sh /azp/start.sh
              RUN chmod +x /azp/start.sh

              WORKDIR /azp/agent

              ENTRYPOINT ["/azp/start.sh"]
              DOCKERFILE

              cat <<'ENTRYPOINT' > start.sh
              #!/bin/bash
              set -e

              if [ -z "$AZP_URL" ]; then
                echo "Error: AZP_URL is not set. Please provide the Azure DevOps organization URL."
                exit 1
              fi

              if [ -z "$AZP_TOKEN" ]; then
                echo "Error: AZP_TOKEN is not set. Please provide a personal access token."
                exit 1
              fi

              if [ -z "$AZP_AGENT_NAME" ]; then
                export AZP_AGENT_NAME="agent-$(hostname)"
              fi

              cd /azp/agent

              ./config.sh --unattended \
                --url "${AZP_URL}" \
                --auth pat \
                --token "${AZP_TOKEN}" \
                --pool "${AZP_POOL:-Default}" \
                --agent "${AZP_AGENT_NAME}" \
                --work /azp/work \
                --acceptTeeEula

              trap './remove.sh' EXIT

              ./run.sh
              ENTRYPOINT
            displayName: "Generate Dockerfile and entrypoint script"

          - task: Docker@2
            displayName: "Build and Push ARM Image"
            inputs:
              command: buildAndPush
              containerRegistry: "$(DOCKER_REGISTRY)"
              repository: "$(IMAGE_NAME)"
              tags: |
                $(IMAGE_TAG)-arm64
                latest-arm64
              Dockerfile: "Dockerfile"
              buildContext: "."

          - bash: |
              echo "##vso[task.setvariable variable=fullImageName]${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}-arm64"
              echo "Built and pushed: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}-arm64"
            displayName: "Output image name"

  - stage: Verify
    displayName: "Verify Agent Image"
    dependsOn: Build
    condition: succeeded()
    jobs:
      - job: VerifyImage
        displayName: "Verify ARM Image"
        steps:
          - bash: |
              echo "Image verification for azure-pipelines-agent ARM64"
              echo "Agent version: $(AGENT_VERSION)"
              echo "Architecture: $(ARCH)"
              echo "Image: $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)-arm64"
              echo ""
              echo "To run the agent, use:"
              echo "  docker run -d \\"
              echo "    -e AZP_URL=https://dev.azure.com/your-org \\"
              echo "    -e AZP_TOKEN=your-pat-token \\"
              echo "    -e AZP_AGENT_NAME=arm-agent \\"
              echo "    -e AZP_POOL=Default \\"
              echo "    $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)-arm64"
            displayName: "Print deployment instructions"
