Param(
    [Parameter(Mandatory=$true)][string] $SourcesDirectory,     # Directory where source files live; if using a Localize directory it should live in here
    [string] $LanguageSet = 'VS_Main_Languages',                # Language set to be used in the LocProject.json
    [switch] $UseCheckedInLocProjectJson,                       # When set, generates a LocProject.json and compares it to one that already exists in the repo; otherwise just generates one
    [switch] $CreateNeutralXlfs                                 # Creates neutral xlf files. Only set to false when running locally
)

# Generates LocProject.json files for the OneLocBuild task. OneLocBuildTask is described here:
# https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task

Set-StrictMode -Version 2.0
$ErrorActionPreference = "Stop"
. $PSScriptRoot\pipeline-logging-functions.ps1

$exclusionsFilePath = "$SourcesDirectory\eng\Localize\LocExclusions.json"
$exclusions = @{ Exclusions = @() }
if (Test-Path -Path $exclusionsFilePath)
{
    $exclusions = Get-Content "$exclusionsFilePath" | ConvertFrom-Json
}

Push-Location "$SourcesDirectory" # push location for Resolve-Path -Relative to work

# Template files
$jsonFiles = @()
$jsonTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\.template\.config\\localize\\.+\.en\.json" } # .NET templating pattern
$jsonTemplateFiles | ForEach-Object {
    $null = $_.Name -Match "(.+)\.[\w-]+\.json" # matches '[filename].[langcode].json

    $destinationFile = "$($_.Directory.FullName)\$($Matches.1).json"
    $jsonFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
}

$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern

$wxlFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\.+\.wxl" -And -Not( $_.Directory.Name -Match "\d{4}" ) } # localized files live in four digit lang ID directories; this excludes them
if (-not $wxlFiles) {
    $wxlEnFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\1033\\.+\.wxl" } #  pick up en files (1033 = en) specifically so we can copy them to use as the neutral xlf files
    if ($wxlEnFiles) {
      $wxlFiles = @()
      $wxlEnFiles | ForEach-Object {
        $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
        $wxlFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
      }
    }
}

$macosHtmlEnFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\.lproj\\.+\.html$" } # add installer HTML files
$macosHtmlFiles = @()
if ($macosHtmlEnFiles) {
    $macosHtmlEnFiles | ForEach-Object {
        $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
        $macosHtmlFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
    }
}

$xlfFiles = @()

$allXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.xlf"
$langXlfFiles = @()
if ($allXlfFiles) {
    $null = $allXlfFiles[0].FullName -Match "\.([\w-]+)\.xlf" # matches '[langcode].xlf'
    $firstLangCode = $Matches.1
    $langXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.$firstLangCode.xlf"
}
$langXlfFiles | ForEach-Object {
    $null = $_.Name -Match "(.+)\.[\w-]+\.xlf" # matches '[filename].[langcode].xlf

    $destinationFile = "$($_.Directory.FullName)\$($Matches.1).xlf"
    $xlfFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
}

$locFiles = $jsonFiles + $jsonWinformsTemplateFiles + $xlfFiles

$locJson = @{
    Projects = @(
        @{
            LanguageSet = $LanguageSet
            LocItems = @(
                $locFiles | ForEach-Object {
                    $outputPath = "$(($_.DirectoryName | Resolve-Path -Relative) + "\")"
                    $continue = $true
                    foreach ($exclusion in $exclusions.Exclusions) {
                        if ($_.FullName.Contains($exclusion))
                        {
                            $continue = $false
                        }
                    }
                    $sourceFile = ($_.FullName | Resolve-Path -Relative)
                    if (!$CreateNeutralXlfs -and $_.Extension -eq '.xlf') {
                        Remove-Item -Path $sourceFile
                    }
                    if ($continue)
                    {
                        if ($_.Directory.Name -eq 'en' -and $_.Extension -eq '.json') {
                            return @{
                                SourceFile = $sourceFile
                                CopyOption = "LangIDOnPath"
                                OutputPath = "$($_.Directory.Parent.FullName | Resolve-Path -Relative)\"
                            }
                        } else {
                            return @{
                                SourceFile = $sourceFile
                                CopyOption = "LangIDOnName"
                                OutputPath = $outputPath
                            }
                        }
                    }
                }
            )
        },
        @{
            LanguageSet = $LanguageSet
            CloneLanguageSet = "WiX_CloneLanguages"
            LssFiles = @( "wxl_loc.lss" )
            LocItems = @(
                $wxlFiles | ForEach-Object {
                    $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
                    $continue = $true
                    foreach ($exclusion in $exclusions.Exclusions) {
                        if ($_.FullName.Contains($exclusion)) {
                            $continue = $false
                        }
                    }
                    $sourceFile = ($_.FullName | Resolve-Path -Relative)
                    if ($continue)
                    {
                        return @{
                            SourceFile = $sourceFile
                            CopyOption = "LangIDOnPath"
                            OutputPath = $outputPath
                        }
                    }
                }
            )
        },
        @{
            LanguageSet = $LanguageSet
            CloneLanguageSet = "VS_macOS_CloneLanguages"
            LssFiles = @( ".\eng\common\loc\P22DotNetHtmlLocalization.lss" )
            LocItems = @(
                $macosHtmlFiles | ForEach-Object {
                    $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
                    $continue = $true
                    foreach ($exclusion in $exclusions.Exclusions) {
                        if ($_.FullName.Contains($exclusion)) {
                            $continue = $false
                        }
                    }
                    $sourceFile = ($_.FullName | Resolve-Path -Relative)
                    $lciFile = $sourceFile + ".lci"
                    if ($continue) {
                        $result = @{
                            SourceFile = $sourceFile
                            CopyOption = "LangIDOnPath"
                            OutputPath = $outputPath
                        }
                        if (Test-Path $lciFile -PathType Leaf) {
                            $result["LciFile"] = $lciFile
                        }
                        return $result
                    }
                }
            )
        }
    )
}

$json = ConvertTo-Json $locJson -Depth 5
Write-Host "LocProject.json generated:`n`n$json`n`n"
Pop-Location

if (!$UseCheckedInLocProjectJson) {
    New-Item "$SourcesDirectory\eng\Localize\LocProject.json" -Force # Need this to make sure the Localize directory is created
    Set-Content "$SourcesDirectory\eng\Localize\LocProject.json" $json
}
else {
    New-Item "$SourcesDirectory\eng\Localize\LocProject-generated.json" -Force # Need this to make sure the Localize directory is created
    Set-Content "$SourcesDirectory\eng\Localize\LocProject-generated.json" $json

    if ((Get-FileHash "$SourcesDirectory\eng\Localize\LocProject-generated.json").Hash -ne (Get-FileHash "$SourcesDirectory\eng\Localize\LocProject.json").Hash) {
        Write-PipelineTelemetryError -Category "OneLocBuild" -Message "Existing LocProject.json differs from generated LocProject.json. Download LocProject-generated.json and compare them."

        exit 1
    }
    else {
        Write-Host "Generated LocProject.json and current LocProject.json are identical."
    }
}
