param(
    [ValidateSet("Debug", "Release")]
    [string]$Configuration = "Debug"
)

$ErrorActionPreference = "Stop"

$projectRoot = $PSScriptRoot
$commonUsageProject = Join-Path $projectRoot "CommonUsage-MultiVehicleSync\commonusage\CommonUsage.csproj"
$medullaProject = Join-Path $projectRoot "MedullaAdapter\MedullaAdapter.csproj"
$multiWheelProject = Join-Path $projectRoot "MultiWheelC\MultiWheelC.csproj"

$commonUsageBuildDirectory = Join-Path $projectRoot "CommonUsage-MultiVehicleSync\commonusage\bin\$Configuration\netstandard2.0"
$commonUsageBuildDll = Join-Path $commonUsageBuildDirectory "CommonUsage.dll"
$commonUsageReferenceDll = Join-Path $projectRoot "ref\CommonUsage.dll"

$medullaBuildDirectory = Join-Path $projectRoot "MedullaAdapter\build\Medulla\plugins"
$multiWheelBuildDirectory = Join-Path $projectRoot "MultiWheelC\build\Clumsy"

$mOutputDirectory = Join-Path $projectRoot "output\M"
$cOutputDirectory = Join-Path $projectRoot "output\C"

function Invoke-ProjectBuild {
    param(
        [Parameter(Mandatory = $true)]
        [string]$ProjectPath
    )

    Write-Host "Building: $ProjectPath" -ForegroundColor Cyan
    & dotnet build $ProjectPath --configuration $Configuration --no-restore

    if ($LASTEXITCODE -ne 0) {
        throw "Build failed: $ProjectPath (dotnet exit code: $LASTEXITCODE)"
    }
}

function Assert-BuildFile {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Path
    )

    if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
        throw "Expected build file was not found: $Path"
    }
}

function Copy-BuildFile {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Source,

        [Parameter(Mandatory = $true)]
        [string]$DestinationDirectory
    )

    Assert-BuildFile -Path $Source
    Copy-Item -LiteralPath $Source -Destination $DestinationDirectory -Force
    Write-Host "Copied: $Source -> $DestinationDirectory" -ForegroundColor DarkGray
}

Write-Host "Building and packaging MyParking. Configuration: $Configuration" -ForegroundColor Green

# CommonUsage must be built first and copied to ref for downstream projects.
Invoke-ProjectBuild -ProjectPath $commonUsageProject
Assert-BuildFile -Path $commonUsageBuildDll

$referenceDirectory = Split-Path -Parent $commonUsageReferenceDll
New-Item -ItemType Directory -Path $referenceDirectory -Force | Out-Null
Copy-Item -LiteralPath $commonUsageBuildDll -Destination $commonUsageReferenceDll -Force
Write-Host "Updated CommonUsage reference: $commonUsageReferenceDll" -ForegroundColor Green

# Build the M and C projects against the updated ref/CommonUsage.dll.
Invoke-ProjectBuild -ProjectPath $medullaProject
Invoke-ProjectBuild -ProjectPath $multiWheelProject

New-Item -ItemType Directory -Path $mOutputDirectory -Force | Out-Null
New-Item -ItemType Directory -Path $cOutputDirectory -Force | Out-Null

# Package the M-layer files.
Copy-BuildFile -Source (Join-Path $medullaBuildDirectory "MedullaAdapter.dll") -DestinationDirectory $mOutputDirectory
Copy-BuildFile -Source (Join-Path $medullaBuildDirectory "MedullaAdapter.pdb") -DestinationDirectory $mOutputDirectory
Copy-BuildFile -Source (Join-Path $medullaBuildDirectory "CommonUsage.dll") -DestinationDirectory $mOutputDirectory

# Package the C-layer files.
Copy-BuildFile -Source (Join-Path $multiWheelBuildDirectory "MultiWheelC.dll") -DestinationDirectory $cOutputDirectory
Copy-BuildFile -Source (Join-Path $multiWheelBuildDirectory "MultiWheelC.pdb") -DestinationDirectory $cOutputDirectory
Copy-BuildFile -Source (Join-Path $multiWheelBuildDirectory "CommonUsage.dll") -DestinationDirectory $cOutputDirectory

Write-Host "" 
Write-Host "Build and packaging completed." -ForegroundColor Green
Write-Host "M output: $mOutputDirectory"
Write-Host "C output: $cOutputDirectory"
