parameters:
  ServiceDirectory: ''
  TestResourcesDirectory: ''
  ArmTemplateParameters: '@{}'
  DeleteAfterHours: 8
  Location: ''
  EnvVars: {}
  SubscriptionConfiguration: '{}'
  ServiceConnection: not-specified
  ResourceType: test
  UseFederatedAuth: true
  PersistOidcToken: false
  SelfContainedPostScript: self-contained-test-resources-post.ps1

# SubscriptionConfiguration will be splatted into the parameters of the test
# resources script. It should be JSON in the form:
# {
#   "SubscriptionId": "<subscription id>",
#   "TenantId": "<tenant id>",
#   "TestApplicationId": "<test app id>",
#   "TestApplicationSecret": "<test app secret>",
#   "ProvisionerApplicationId": "<provisioner app id>",
#   "ProvisionerApplicationSecret": "<provisioner app secret>",
#   "Environment": "AzureCloud | AzureGov | AzureChina | <other environment>"
#   "EnvironmentVariables": {
#       "SERVICE_MANAGEMENT_URL": "<service management url>",
#       "STORAGE_ENDPOINT_SUFFIX": "<storage endpoint suffix>",
#       "RESOURCE_MANAGER_URL": "<resource manager url>",
#       "SEARCH_ENDPOINT_SUFFIX": "<search endpoint suffix>",
#       "COSMOS_TABLES_ENDPOINT_SUFFIX": "<cosmos tables endpoint suffix>"
#   },
#   "ArmTemplateParameters": {
#       "keyVaultDomainSuffix": "<keyVaultDomainSuffix>",
#       "storageEndpointSuffix": "<storageEndpointSuffix>",
#       "endpointSuffix": "<endpointSuffix>",
#       "azureAuthorityHost": "<azureAuthorityHost>",
#       "keyVaultEndpointSuffix": "<keyVaultEndpointSuffix>"
#   }
# }

steps:
  - template: /eng/common/pipelines/templates/steps/cache-ps-modules.yml

  - template: /eng/common/TestResources/setup-environments.yml

  - ${{ if eq(parameters.PersistOidcToken, true) }}:
    - task: AzureCLI@2
      displayName: Set OIDC token
      env:
        ARM_OIDC_TOKEN: $(ARM_OIDC_TOKEN)
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        addSpnToEnvironment: true
        scriptLocation: inlineScript
        scriptType: pscore
        inlineScript: |
          Write-Host "##vso[task.setvariable variable=ARM_OIDC_TOKEN;issecret=true]$($env:idToken)"

  - ${{ if eq('true', parameters.UseFederatedAuth) }}:
    - task: AzurePowerShell@5
      displayName: 🚀 Deploy test resources
      env:
        TEMP: $(Agent.TempDirectory)
        PoolSubnet: $(PoolSubnet)
        ${{ if eq(parameters.PersistOidcToken, true) }}:
          ARM_OIDC_TOKEN: $(ARM_OIDC_TOKEN)
        ${{ insert }}: ${{ parameters.EnvVars }}
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        azurePowerShellVersion: LatestVersion
        pwsh: true
        ScriptType: InlineScript
        Inline: |
          eng/common/scripts/Import-AzModules.ps1
          $subscriptionConfiguration = @'
            ${{ parameters.SubscriptionConfiguration }}
          '@ | ConvertFrom-Json -AsHashtable;

          $context = Get-AzContext
          $subscriptionConfiguration["Environment"] = $context.Environment.Name
          $subscriptionConfiguration["SubscriptionId"] = $context.Subscription.Id
          $subscriptionConfiguration["TenantId"] = $context.Subscription.TenantId
          $subscriptionConfiguration["TestApplicationId"] = $context.Account.Id
          $subscriptionConfiguration["ProvisionerApplicationId"] = $context.Account.Id

          $principal = Get-AzADServicePrincipal -ApplicationId $context.Account.Id
          $subscriptionConfiguration["TestApplicationOid"] = $principal.Id
          $subscriptionConfiguration["ProvisionerApplicationOid"] = $principal.Id

          Write-Host ($subscriptionConfiguration | ConvertTo-Json)
          # Write the new SubscriptionConfiguration to be used by the remove test resources
          Write-Host "##vso[task.setvariable variable=SubscriptionConfiguration;]$($subscriptionConfiguration | ConvertTo-Json -Compress)"

          $postScriptPath = $${{ parameters.PersistOidcToken }} ? '$(Agent.TempDirectory)/${{ parameters.SelfContainedPostScript }}' : $null

          # The subscriptionConfiguration may have ArmTemplateParameters defined, so
          # pass those in via the ArmTemplateParameters flag, and handle any
          # additional parameters from the pipelines via AdditionalParameters
          eng/common/TestResources/New-TestResources.ps1 `
            -ResourceType '${{ parameters.ResourceType }}' `
            -ServiceDirectory '${{ parameters.ServiceDirectory }}' `
            -TestResourcesDirectory '${{ parameters.TestResourcesDirectory }}' `
            -Location '${{ parameters.Location }}' `
            -DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
            @subscriptionConfiguration `
            -AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
            -AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
            -SelfContainedPostScript $postScriptPath `
            -CI `
            -Force `
            -Verbose | Out-Null

    - ${{ if eq(parameters.PersistOidcToken, true) }}:
      # ARM deployments that take longer than 10-15 minutes (e.g. HSM) can
      # cause post scripts to fail with expired credentials.
      # Add a new task with a refreshed token as a workaround to this issue.
      - task: AzureCLI@2
        displayName: Test Resources Post with refreshed login
        env:
          ${{ insert }}: ${{ parameters.EnvVars }}
        inputs:
          azureSubscription: ${{ parameters.ServiceConnection }}
          addSpnToEnvironment: true
          scriptLocation: inlineScript
          scriptType: pscore
          inlineScript: |
            eng/common/scripts/Import-AzModules.ps1  # Support post scripts using az powershell instead of az cli
            $env:ARM_OIDC_TOKEN = $env:idToken
            $scriptPath = '$(Agent.TempDirectory)/${{ parameters.SelfContainedPostScript }}'
            Write-Host "Executing self contained test resources post script '$scriptPath'"
            & $scriptPath
            Remove-Item $scriptPath  # avoid any possible complications when we run multiple deploy templates

  - ${{ else }}:
    - pwsh: |
        eng/common/scripts/Import-AzModules.ps1
        $subscriptionConfiguration = @'
          ${{ parameters.SubscriptionConfiguration }}
        '@ | ConvertFrom-Json -AsHashtable;

        # The subscriptionConfiguration may have ArmTemplateParameters defined, so
        # pass those in via the ArmTemplateParameters flag, and handle any
        # additional parameters from the pipelines via AdditionalParameters
        eng/common/TestResources/New-TestResources.ps1 `
          -ResourceType '${{ parameters.ResourceType }}' `
          -ServiceDirectory '${{ parameters.ServiceDirectory }}' `
          -TestResourcesDirectory '${{ parameters.TestResourcesDirectory }}' `
          -Location '${{ parameters.Location }}' `
          -DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
          @subscriptionConfiguration `
          -AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
          -AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
          -CI `
          -ServicePrincipalAuth `
          -Force `
          -Verbose | Out-Null
      displayName: 🚀 Deploy test resources
      env:
        TEMP: $(Agent.TempDirectory)
        PoolSubnet: $(PoolSubnet)
        ${{ insert }}: ${{ parameters.EnvVars }}
