stages:
  - build
  - publish

# Only create pipelines automatically when a Git tag is pushed.
# Otherwise the pipeline must be started manually (pipeline "Run" / dispatch equivalent).
# workflow:
#   rules:
#     - if: '$CI_COMMIT_TAG'
#       when: always
#     - if: '$CI_PIPELINE_SOURCE == "web"'
#       when: always
#     - when: never

variables:
  DOTNET_CLI_TELEMETRY_OPTOUT: "1"
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1"
  BUILD_CONFIG: "Release"
  # NOTE: This project uses repository variables for NuGet auth because secrets
  # (masked/protected variables) may not be available on your GitLab plan.
  # Replace the placeholders below with values in the repository, or override
  # them in your project CI/CD variables when available.
  # - NUGET_USERNAME : username (can be any value when using a PAT)
  # - NUGET_PASSWORD : personal access token or project deploy token
  NUGET_USERNAME: "REPLACE_WITH_USERNAME"
  NUGET_PASSWORD: "REPLACE_WITH_TOKEN"

# Build job for Windows runner (shell executor). Remove 'image' so the runner uses the host environment.
build_windows:
  stage: build
  tags:
    - saas-windows-medium-amd64
  script:
    - |
      powershell -NoProfile -Command {
        $needsInstall = -not (dotnet --list-sdks 2>$null | Select-String '^10\.')
        if ($needsInstall) {
          Write-Host 'Installing .NET 10 SDK using dotnet-install.ps1'
          Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1 -UseBasicParsing
          .\dotnet-install.ps1 -Channel 10.0 -InstallDir $env:USERPROFILE\.dotnet
          $dotnetExe = Join-Path $env:USERPROFILE '.dotnet\dotnet.exe'
        } else {
          Write-Host '.NET 10 SDK already present on PATH'
          $dotnetExe = 'dotnet'
        }

        # Configure private NuGet source from GitLab Packages using CI_JOB_TOKEN
        # Fallback to repository variables NUGET_USERNAME/NUGET_PASSWORD for shared runners
        $nugetUrl = 'https://gitlab.com/api/v4/projects/79509532/packages/nuget/index.json'
        $authMode = $null
        if ($env:CI_JOB_TOKEN) {
          Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using CI_JOB_TOKEN...'
          try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
          & $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username gitlab-ci-token --password $env:CI_JOB_TOKEN --store-password-in-clear-text
          $authMode = 'JobToken'
        } elseif ($env:NUGET_USERNAME -and $env:NUGET_PASSWORD) {
          Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using NUGET_USERNAME/NUGET_PASSWORD...'
          try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
          & $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username $env:NUGET_USERNAME --password $env:NUGET_PASSWORD --store-password-in-clear-text
          $authMode = 'UserCreds'
        } else {
          Write-Host 'No credentials available; skipping private NuGet source configuration.'
        }

        & $dotnetExe --info
        # Diagnostic: verify GitLab NuGet feed and package visibility using configured auth
        if ($authMode) {
          Write-Host 'Checking GitLab NuGet feed index and project packages for AIFotoONLUS.Core using auth mode:' $authMode
          try {
            if ($authMode -eq 'JobToken') {
              $headers = @{ 'JOB-TOKEN' = $env:CI_JOB_TOKEN }
            } else {
              $pair = "$env:NUGET_USERNAME:$env:NUGET_PASSWORD"
              $b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
              $headers = @{ Authorization = "Basic $b64" }
            }
            Invoke-RestMethod -Uri $nugetUrl -Headers $headers -Method Get | ConvertTo-Json | Write-Host
          } catch { Write-Host "Failed to fetch feed index: $_" }
          try {
            $pkgApi = "https://gitlab.com/api/v4/projects/79509532/packages?package_name=AIFotoONLUS.Core"
            Invoke-RestMethod -Uri $pkgApi -Headers $headers -Method Get | ConvertTo-Json | Write-Host
          } catch { Write-Host "Failed to query project packages API: $_" }
        } else {
          Write-Host 'Skipping feed diagnostics because no auth configured.'
        }
        & $dotnetExe restore
        & $dotnetExe build "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -v minimal
        # Produce a single-file, ready-to-run publish so downstream jobs only need the EXE.
        try {
          & $dotnetExe publish "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -r win-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=false -p:PublishReadyToRun=true -o "imagecatalog\bin\$env:BUILD_CONFIG\net10.0-windows\publish" -v minimal
        } catch {
          Write-Host "dotnet publish failed: $_"
          throw
        }
      }
  artifacts:
    paths:
      - "imagecatalog/bin/$BUILD_CONFIG/net10.0-windows/publish/**"
    expire_in: 1 hour

# Publish and create GitLab Release when building a tag.
publish_release:
  stage: publish
  image: mcr.microsoft.com/dotnet/sdk:10.0
  variables:
    GIT_DEPTH: 0
  needs:
    - job: build_windows
      artifacts: true
  script: |
    set -euo pipefail
    dotnet --info
    export PATH="$PATH:$HOME/.dotnet/tools"
    echo "Installing minver-cli"
    dotnet tool install --global minver-cli --version 7.0.0
    # Ensure we have full git history and tags for MinVer to compute an accurate version
    git fetch --prune --unshallow || true
    git fetch --tags || true
    echo "Computing version with minver-cli"
    version=$(minver 2>/dev/null | tail -n1 || true)
    if [ -z "$version" ]; then echo "minver failed to produce a version"; exit 1; fi
    echo "Using version: $version"
    export VERSION="$version"
    # find the single-file exe from the publish output
    file=$(find imagecatalog/bin -type f -iname '*.exe' -print | head -n1 || true)
    if [ -z "$file" ]; then file=$(find imagecatalog -type f -iname '*.exe' -print | head -n1 || true); fi
    if [ -z "$file" ]; then echo "No artifact EXE found to attach"; exit 1; fi
    echo "Uploading artifact: $file"
    uploadResp=$(curl --silent --show-error --header "JOB-TOKEN:$CI_JOB_TOKEN" --form "file=@$file" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/uploads")
    assetPath=$(echo "$uploadResp" | sed -n 's/.*"url":"\([^\"]*\)".*/\1/p')
    if [ -z "$assetPath" ]; then echo "Upload failed: $uploadResp"; exit 1; fi
    assetUrl="$CI_SERVER_URL$assetPath"
    echo "Uploaded asset url: $assetUrl"
    basename=$(basename "$file")
    export RELEASE_ASSET_URL="$assetUrl"
    export ASSET_BASENAME="$basename"
  artifacts:
    expire_in: 1 day
  release:
    tag_name: "$VERSION"
    name: "Release $VERSION"
    description: "Automated release from CI (version $VERSION)"
    assets:
      links:
        - name: "$ASSET_BASENAME"
          url: "$RELEASE_ASSET_URL"
#  only:
#    - tags

# Notes for runner setup: The job now runs on the public .NET SDK image and downloads artifacts from the
# `build_windows` job via `needs`. It reads the `minversion` file produced by the build artifacts and
# uses that value as the release tag.
