# -----------------------------------------------------------------------------------
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the ""License""); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an ""AS IS"" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------------------------

<#
 .SYNOPSIS
    Generates GitHub Actions workflows for running tests upon a pull request action (either a
    new pull request or a push to an existing one).

 .DESCRIPTION
    Generates 1 GitHub Actions workflow file for each project containing the string ".Tests"
    in the name. The current project, ProjectReference dependencies, and common files
    Directory.Build.*, TestTargetFraemworks.*, TestReferences.Common.* and Dependencies.props
    are all used to build filter paths to determine when the workflow will run.

 .PARAMETER OutputDirectory
    The directory to output the files. This should be in a directory named /.github/workflows
    in the root of the repository. The default is the directory of this script file.

 .PARAMETER RepoRoot
    The directory of the repository root. Defaults to two levels above the directory
    of this script file.

 .PARAMETER TestFrameworks
    A string array of Dotnet target framework monikers to run the tests on. The default is
    @('net5.0','netcoreapp2.1','net48').

 .PARAMETER OperatingSystems
    A string array of Github Actions operating system monikers to run the tests on.
    The default is @('windows-latest', 'ubuntu-latest').

 .PARAMETER TestPlatforms
    A string array of platforms to run the tests on. Valid values are x64 and x86.
    The default is @('x64').

 .PARAMETER Configurations
    A string array of build configurations to run the tests on. The default is @('Release').

 .PARAMETER DotNet5SDKVersion
    The SDK version of .NET 5.x to install on the build agent to be used for building and
    testing. This SDK is always installed on the build agent. The default is 5.0.100.

 .PARAMETER DotNetCore3SDKVersion
    The SDK version of .NET Core 3.x to install on the build agent to be used for building and
    testing. This SDK is only installed on the build agent when targeting .NET Core 3.x.
    The default is 3.1.404.

 .PARAMETER DotNetCore2SDKVersion
    The SDK version of .NET Core 2.x to install on the build agent to be used for building and
    testing. This SDK is only installed on the build agent when targeting .NET Core 2.x.
    The default is 2.1.811.
#>
param(
    [string]$OutputDirectory =  $PSScriptRoot,

    [string]$RepoRoot = (Split-Path (Split-Path $PSScriptRoot)),

    [string[]]$TestFrameworks = @('net5.0','netcoreapp2.1','net48'),

    [string[]]$OperatingSystems = @('windows-latest', 'ubuntu-latest'),

    [string[]]$TestPlatforms = @('x64'),

    [string[]]$Configurations = @('Release'),

    [string]$DotNet5SDKVersion = '5.0.100',

    [string]$DotNetCore3SDKVersion = '3.1.404',

    [string]$DotNetCore2SDKVersion = '2.1.811'
)


function Resolve-RelativePath([string]$RelativeRoot, [string]$Path) {
    Push-Location -Path $RelativeRoot
    try {
        return Resolve-Path $Path -Relative
    } finally {
        Pop-Location
    }
}

function Get-ProjectDependencies([string]$ProjectPath, [string]$RelativeRoot, [System.Collections.Generic.HashSet[string]]$Result) {
    $resolvedProjectPath = $ProjectPath
    $rootPath = [System.IO.Path]::GetDirectoryName($resolvedProjectPath)
    [xml]$project = Get-Content $resolvedProjectPath
    foreach ($name in $project.SelectNodes("//Project/ItemGroup/ProjectReference") | ForEach-Object { $_.Include -split ';'}) {
        $dependencyFullPath = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($rootPath, $name))
        Get-ProjectDependencies $dependencyFullPath $RelativeRoot $Result
        $dependency = Resolve-RelativePath $RelativeRoot $dependencyFullPath
        $result.Add($dependency) | Out-Null
    }
}

function Get-ProjectPathDirectories([string]$ProjectPath, [string]$RelativeRoot, [System.Collections.Generic.HashSet[string]]$Result) {
    $currentPath = New-Object System.IO.DirectoryInfo([System.IO.Path]::GetDirectoryName($ProjectPath))
    $currentRelativePath = Resolve-RelativePath $RelativeRoot $currentPath.FullName
    $Result.Add($currentRelativePath) | Out-Null
    while ($true) {
        $prevDirectory = New-Object System.IO.DirectoryInfo($currentPath.FullName)
        $currentPath = $prevDirectory.Parent
        if ($currentPath -eq $null) {
            break
        }
        if ($currentPath.FullName -eq $RelativeRoot) {
            $Result.Add(".") | Out-Null
            break
        }
        $currentRelativePath = Resolve-RelativePath $RelativeRoot $currentPath.FullName
        $Result.Add($currentRelativePath) | Out-Null
    }
}

function Ensure-Directory-Exists([string] $path) {
    if (!(Test-Path $path)) {
        New-Item $path -ItemType Directory
    }
}

function Write-TestWorkflow(
    [string]$OutputDirectory = $PSScriptRoot, #optional
    [string]$RelativeRoot,
    [string]$ProjectPath,
    [string[]]$Configurations = @('Release'),
    [string[]]$TestFrameworks = @('net5.0', 'net48'),
    [string[]]$TestPlatforms = @('x64'),
    [string[]]$OperatingSystems = @('windows-latest', 'ubuntu-latest', 'macos-latest'),
    [string]$DotNet5SDKVersion = $DotNet5SDKVersion,
    [string]$DotNetCore3SDKVersion = $DotNetCore3SDKVersion,
    [string]$DotNetCore2SDKVersion = $DotNetCore2SDKVersion) {

    $dependencies = New-Object System.Collections.Generic.HashSet[string]
    Get-ProjectDependencies $ProjectPath $RelativeRoot $dependencies
    $dependencyPaths = [System.Environment]::NewLine
    foreach ($dependency in $dependencies) {
        $dependencyRelativeDirectory = ([System.IO.Path]::GetDirectoryName($dependency) -replace '\\', '/').TrimStart('./')
        $dependencyPaths += "    - '$dependencyRelativeDirectory/**/*'" + [System.Environment]::NewLine
    }

    $projectRelativePath = $(Resolve-RelativePath $RelativeRoot $ProjectPath) -replace '\\', '/'
    $projectRelativeDirectory = ([System.IO.Path]::GetDirectoryName($projectRelativePath) -replace '\\', '/').TrimStart('./')
    $projectName = [System.IO.Path]::GetFileNameWithoutExtension($ProjectPath)

    [string]$frameworks = '[' + $($TestFrameworks -join ', ') + ']'
    [string]$platforms = '[' + $($TestPlatforms -join ', ') + ']'
    [string]$oses = '[' + $($OperatingSystems -join ', ') + ']'
    [string]$configurations = '[' + $($Configurations -join ', ') + ']'

    $directories = New-Object System.Collections.Generic.HashSet[string]
    Get-ProjectPathDirectories $projectPath $RepoRoot $directories

    $directoryBuildPaths = [System.Environment]::NewLine
    foreach ($directory in $directories) {
        $relativeDirectory = ([System.IO.Path]::Combine($directory, 'Directory.Build.*') -replace '\\', '/').TrimStart('./')
        $directoryBuildPaths += "    - '$relativeDirectory'" + [System.Environment]::NewLine
    }

    $fileText = "####################################################################################
# DO NOT EDIT: This file was automatically generated by Generate-TestWorkflows.ps1
####################################################################################
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# `"License`"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# `"AS IS`" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: '$projectName'

on:
  workflow_dispatch:
  pull_request:
    paths:
    - '$projectRelativeDirectory/**/*'
    - 'build/Dependencies.props'
    - 'build/TestReferences.Common.*'
    - 'TestTargetFrameworks.*'
    - '*.sln'$directoryBuildPaths
    # Dependencies$dependencyPaths
    - '!**/*.md'

jobs:

  Test:
    runs-on: `${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: $oses
        framework: $frameworks
        platform: $platforms
        configuration: $configurations
        exclude:
          - os: ubuntu-latest
            framework: net48
          - os: macos-latest
            framework: net48
    env:
      project_path: '$projectRelativePath'
      trx_file_name: 'TestResults.trx'
      md_file_name: 'TestResults.md' # Report file name for LiquidTestReports.Markdown

    steps:
      - uses: actions/checkout@v2

      - name: Setup .NET 3.1 SDK
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '$DotNetCore3SDKVersion'
        if: `${{ startswith(matrix.framework, 'netcoreapp3.') }}

      - name: Setup .NET 2.1 SDK
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '$DotNetCore2SDKVersion'
        if: `${{ startswith(matrix.framework, 'netcoreapp2.') }}

      - name: Setup .NET 5 SDK
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '$DotNet5SDKVersion'

      - run: |
          `$project_name = [System.IO.Path]::GetFileNameWithoutExtension(`$env:project_path)
          `$test_results_artifact_name = `"testresults_`${{matrix.os}}_`${{matrix.framework}}_`${{matrix.platform}}_`${{matrix.configuration}}`"
          Write-Host `"Project Name: `$project_name`"
          Write-Host `"Results Artifact Name: `$test_results_artifact_name`"
          echo `"project_name=`$project_name`" | Out-File -FilePath  `$env:GITHUB_ENV -Encoding utf8 -Append
          echo `"test_results_artifact_name=`$test_results_artifact_name`" | Out-File -FilePath  `$env:GITHUB_ENV -Encoding utf8 -Append
          # Title for LiquidTestReports.Markdown
          echo `"title=Test Run for `$project_name - `${{matrix.framework}} - `${{matrix.platform}} - `${{matrix.os}}`" | Out-File -FilePath  `$env:GITHUB_ENV -Encoding utf8 -Append
        shell: pwsh
      - run: dotnet build `${{env.project_path}} --configuration `${{matrix.configuration}} --framework `${{matrix.framework}} /p:TestFrameworks=true
      - run: dotnet test `${{env.project_path}} --configuration `${{matrix.configuration}} --framework `${{matrix.framework}} --no-build --no-restore --blame-hang --blame-hang-dump-type mini --blame-hang-timeout 20minutes --logger:`"console;verbosity=normal`" --logger:`"trx;LogFileName=`${{env.trx_file_name}}`" --logger:`"liquid.md;LogFileName=`${{env.md_file_name}};Title=`${{env.title}};`" --results-directory:`"`${{github.workspace}}/`${{env.test_results_artifact_name}}/`${{env.project_name}}`" -- RunConfiguration.TargetPlatform=`${{matrix.platform}}
      # upload reports as build artifacts
      - name: Upload a Build Artifact
        uses: actions/upload-artifact@v2
        if: `${{always()}}
        with:
          name: '`${{env.test_results_artifact_name}}'
          path: '`${{github.workspace}}/`${{env.test_results_artifact_name}}'
"

    # GitHub Actions does not support filenames with "." in them, so replace
    # with "-"
    $projectFileName = $projectName -replace '\.', '-'
    $FilePath = "$OutputDirectory/$projectFileName.yml"

    #$dir = [System.IO.Path]::GetDirectoryName($File)
    Ensure-Directory-Exists $OutputDirectory

    Write-Host "Generating workflow file: $FilePath"
    Out-File -filePath $FilePath -encoding UTF8 -inputObject $fileText

    #Write-Host $fileText
}


Push-Location $RelativeRoot
try {
    [string[]]$TestProjects = Get-ChildItem -Path "$RepoRoot/**/*.csproj" -Recurse | where { $_.Directory.Name.Contains(".Tests") -and !($_.Directory.FullName.Contains('svn-')) } | Select-Object -ExpandProperty FullName
} finally {
    Pop-Location
}


#Write-TestWorkflow -OutputDirectory $OutputDirectory -ProjectPath $projectPath -RelativeRoot $repoRoot -TestFrameworks @('net5.0','netcoreapp3.1') -TestPlatforms $TestPlatforms

#Write-Host $TestProjects

foreach ($testProject in $TestProjects) {
    $projectName = [System.IO.Path]::GetFileNameWithoutExtension($testProject)
    [string[]]$frameworks = $TestFrameworks

    # Special case - CodeAnalysis only supports .NET Core 2.1 for testing
    if ($projectName.Contains("Tests.CodeAnalysis")) {
        $frameworks = @('netcoreapp2.1')
    }

    # Special case - our CLI tool only supports .NET Core 3.1
    if ($projectName.Contains("Tests.Cli")) {
        $frameworks = @('netcoreapp3.1')
    }

    # Special case - OpenNLP.NET only supports .NET Framework
    if ($projectName.Contains("Tests.Analysis.OpenNLP")) {
        $frameworks = @('net48')
    }

    #Write-Host "Project: $projectName"
    Write-TestWorkflow -OutputDirectory $OutputDirectory -ProjectPath $testProject -RelativeRoot $RepoRoot -TestFrameworks $frameworks -OperatingSystems $OperatingSystems -TestPlatforms $TestPlatforms -Configurations $Configurations -DotNet5SDKVersion $DotNet5SDKVersion -DotNetCore3SDKVersion $DotNetCore3SDKVersion -DotNetCore2SDKVersion $DotNetCore2SDKVersion
}