parameters:
- name: ApplicationName
  type: string
- name: PathToSearch
  type: string

steps:
- task: PowerShell@2
  displayName: Update Semantic Versioning in AssemblyInfo Files
  inputs:
    targetType: inline
    script: |
      [string]$ApplicationName = '${{parameters.ApplicationName}}'
      [string]$PathToSearch = '${{parameters.PathToSearch}}'
      [string]$BuildNumber = $env:BUILD_BUILDNUMBER
      [string]$SearchFilter = 'AssemblyInfo.*'

      [string]$PatternSplitCharacters = '.'
      [regex]$Pattern = '\d+\.\d+\.\d+\.\d+'
      [int]$PatternExpectedVersionNumbers = 4
      [int]$VersionNumbersInVersion = 4

      Function Replace-Version() {
        param(
          [Parameter(Mandatory = $true)] $content,
          [Parameter(Mandatory = $true)] [string]$version,
          [Parameter(Mandatory = $true)] [string]$attribute
        )

        $exitFunction = $false

        foreach ($line in $content) {
          if ($line -match 'exclude from semantic versioning') {
            Write-Host "  * Skipping $attribute due to exclude"
            $exitFunction = $true
          }

          if ($line -match 'include semantic versioning' -and $line -notmatch "include semantic versioning - $ApplicationName") {
            Write-Host "  * Skipping $attribute due to include not matching"
            $exitFunction = $true
          }
        }

        if ($exitFunction) {
          return $content
        }

        $versionAttribute = "[assembly: $attribute(""$version"")]"
        $pattern = "\[assembly: $attribute\("".*""\)\]"
        $versionReplaced = $false

        $content = $content | % {
          if ($_ -match $Pattern) {
            $versionReplaced = $true
            $_ = $_ -replace [regex]::Escape($Matches[0]),$versionAttribute
            Write-Host "  * Replaced $($Matches[0]) with $versionAttribute"
          }
          $_
        }

        return $content
      }

      Function Get-VersionString() {
        param(
          [Parameter(Mandatory = $true)] [int]$numberOfVersions,
          [Parameter(Mandatory = $true)] $extractedBuildNumbers
        )

        return [string]::Join('.',($extractedBuildNumbers | select -First ($numberOfVersions)))
      }

      if ($BuildNumber -match $Pattern -ne $true) {
        Write-Host "Could not extract a version from [$BuildNumber] using pattern [$Pattern]"
        exit 2
      }

      # Set version variables
      $extractedBuildNumbers = @($Matches[0].Split(([char[]]$PatternSplitCharacters)))
      if ($extractedBuildNumbers.Length -ne $PatternExpectedVersionNumbers) {
        Write-Host "The extracted build number $($Matches[0]) does not contain the expected $PatternExpectedVersionNumbers elements"
        exit 2
      }

      $version = Get-VersionString -numberOfVersions $VersionNumbersInVersion -extractedBuildNumbers $extractedBuildNumbers
      $fileVersion = Get-VersionString -numberOfVersions $VersionNumbersInVersion -extractedBuildNumbers $extractedBuildNumbers
      Write-Host "Using version $version and file version $fileVersion"

      $files = Get-ChildItem -Path $PathToSearch -Filter $SearchFilter -Recurse
      foreach ($file in $files) {
        Write-Host "-> Checking $($file.FullName)"

        # remove the read-only bit on the file
        Set-ItemProperty $file.FullName -name IsReadOnly -value $false

        # run the regex replace
        $content = Get-Content $file.FullName
        $content = Replace-Version -content $content -version $version -attribute 'AssemblyVersion'
        $content = Replace-Version -content $content -version $fileVersion -attribute 'AssemblyFileVersion'
        $content | Set-Content $file.FullName -Encoding UTF8
      }
    pwsh: true
