# =============================================================================
# Mergin Maps Mobile - GitLab CI/CD Pipeline (Two-Stage Build with Podman)
# =============================================================================
# This pipeline builds the Mergin Maps Mobile application using two separate
# images: a base environment image and a build image. This approach optimizes
# layer caching and makes images more reusable.
#
# Features:
# - Two-stage build process: base environment + build image
# - Volume sharing between images for dependency reuse
# - Automatic triggering on push to any branch
# - Multi-stage Podman build with optimized caching
# - Standardized image tagging (semver, latest, date, git hash)
# - APK artifact extraction and storage
# - Rootless container execution for enhanced security
# - External dependencies managed via Artifactory variables
# =============================================================================

# Global variables
variables:
  # Podman configuration
  PODMAN_HOST: "unix:///run/user/$(id -u)/podman/podman.sock"
  CONTAINER_RUNTIME: "podman"
  
  # Image configuration
  BASE_IMAGE_NAME: "mergin-maps-base"
  BUILD_IMAGE_NAME: "mergin-maps-build"
  REGISTRY_URL: "$CI_REGISTRY"
  FULL_IMAGE_NAME: "$REGISTRY_URL/$CI_PROJECT_PATH"
  
  # Artifactory URLs for external dependencies (variables from GitLab CI)
  ANDROID_SDK_URL: "https://mirror.dev.futurmap.net/sdk_android.tgz"
  MERGIN_SDK_ARM_URL: "https://mirror.dev.futurmap.net/arm-android.tar.gz"
  MERGIN_SDK_ARM64_URL: "https://mirror.dev.futurmap.net/arm64-android.tar.gz"
  GRADLE_URL: "https://mirror.dev.futurmap.net/sdk_android/gradle.zip"
  
  # APK configuration
  APK_SOURCE_PATH: "/var/www/mergin-maps/build/app/android-build/build/outputs/apk/release/android-build-release.apk"
  APK_ARTIFACT_NAME: "mergin-maps-mobile.apk"

# Pipeline stages
stages:
  - cleanup
  - base_build
  - build_image
  - apk_export

# =============================================================================
# STAGE 1: CLEANUP - Clean up Podman resources
# =============================================================================
cleanup_podman:
  stage: cleanup
  image: quay.io/podman/stable:latest
  tags:
    - build-mergin-maps
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
      when: always
  script:
    - echo "🧹 Cleaning up Podman resources..."
    - podman system prune -f || true
    - podman image prune -f || true
    - echo "✅ Cleanup completed"
  allow_failure: true

# =============================================================================
# STAGE 2: BASE BUILD - Build base environment image
# =============================================================================
build_base_image:
  stage: base_build
  image: quay.io/podman/stable:latest
  tags:
    - build-mergin-maps
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
  before_script:
    - 'echo "🚀 Starting base environment build..."'
    - 'echo "Branch: $CI_COMMIT_REF_NAME"'
    - 'echo "Commit: $CI_COMMIT_SHORT_SHA"'
    - 'echo "Pipeline: $CI_PIPELINE_ID"'
    # Initialize Podman for rootless operation
    - podman unshare --help > /dev/null || true
  script:
    # Generate standardized tag for base image
    - |
      if [[ "$CI_COMMIT_REF_NAME" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        export BASE_IMAGE_TAG="base-$CI_COMMIT_REF_NAME"
        echo "Using base version tag: $BASE_IMAGE_TAG"
      else
        export BASE_IMAGE_TAG="base-commit-$CI_COMMIT_SHORT_SHA"
        echo "Using base commit tag: $BASE_IMAGE_TAG"
      fi
    
    # Build the base environment image with all dependencies
    - 'echo "🔨 Building base environment image: $BASE_IMAGE_NAME:$BASE_IMAGE_TAG"'
    - |
      podman build \
        --network=host \
        --tag "$BASE_IMAGE_NAME:$BASE_IMAGE_TAG" \
        --tag "$BASE_IMAGE_NAME:latest" \
        --tag "$BASE_IMAGE_NAME:commit-$CI_COMMIT_SHORT_SHA" \
        --build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
        --build-arg VCS_REF="$CI_COMMIT_SHA" \
        --build-arg VERSION="$BASE_IMAGE_TAG" \
        --build-arg ANDROID_SDK_URL="$ANDROID_SDK_URL" \
        --build-arg MERGIN_SDK_ARM_URL="$MERGIN_SDK_ARM_URL" \
        --build-arg MERGIN_SDK_ARM64_URL="$MERGIN_SDK_ARM64_URL" \
        --build-arg GRADLE_URL="$GRADLE_URL" \
        -f Dockerfile.base \
        .
    
    # Verify the base image was built successfully
    - 'echo "✅ Base environment image built successfully"'
    - 'podman images | grep "$BASE_IMAGE_NAME"'
    
    # Save base image info for next stage
    - 'echo "$BASE_IMAGE_NAME:$BASE_IMAGE_TAG" > base_image_tag.txt'
    - 'echo "$BASE_IMAGE_NAME:latest" > base_image_latest.txt'
    
    # Create environment file with image info
    - |
      cat > base.env << EOF
      BASE_IMAGE_TAG=$BASE_IMAGE_TAG
      BASE_IMAGE_NAME=$BASE_IMAGE_NAME
      EOF
  artifacts:
    reports:
      dotenv: base.env
    paths:
      - base_image_tag.txt
      - base_image_latest.txt
    expire_in: 1 hour
  cache:
    key: "base-image-cache-$CI_COMMIT_REF_SLUG"
    paths:
      - .podman-cache/
    policy: pull-push

# =============================================================================
# STAGE 3: BUILD IMAGE - Build application using base image
# =============================================================================
build_application_image:
  stage: build_image
  image: quay.io/podman/stable:latest
  tags:
    - build-mergin-maps
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
  dependencies:
    - build_base_image
  before_script:
    - 'echo "🔨 Starting application build..."'
    - 'echo "Using base image: $BASE_IMAGE_NAME:$BASE_IMAGE_TAG"'
    # Initialize Podman for rootless operation
    - podman unshare --help > /dev/null || true
  script:
    # Generate standardized tag for build image
    - |
      if [[ "$CI_COMMIT_REF_NAME" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        export BUILD_IMAGE_TAG="build-$CI_COMMIT_REF_NAME"
        echo "Using build version tag: $BUILD_IMAGE_TAG"
      else
        export BUILD_IMAGE_TAG="build-commit-$CI_COMMIT_SHORT_SHA"
        echo "Using build commit tag: $BUILD_IMAGE_TAG"
      fi
    
    # Update the build Dockerfile to use the correct base image
    - 'echo "📝 Updating build Dockerfile to use base image: $BASE_IMAGE_NAME:$BASE_IMAGE_TAG"'
    - sed -i "s|FROM mergin-maps-base:latest|FROM $BASE_IMAGE_NAME:$BASE_IMAGE_TAG|g" Dockerfile.build
    
    # Build the application image using the base image
    # All dependencies are already available in the base image via shared volume
    - 'echo "🔨 Building application image: $BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG"'
    - |
      podman build \
        --network=host \
        --tag "$BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG" \
        --tag "$BUILD_IMAGE_NAME:latest" \
        --tag "$BUILD_IMAGE_NAME:commit-$CI_COMMIT_SHORT_SHA" \
        --build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
        --build-arg VCS_REF="$CI_COMMIT_SHA" \
        --build-arg VERSION="$BUILD_IMAGE_TAG" \
        -f Dockerfile.build \
        .
    
    # Verify the build image was created successfully
    - 'echo "✅ Application image built successfully"'
    - 'podman images | grep "$BUILD_IMAGE_NAME"'
    
    # Save build image info for next stage
    - 'echo "$BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG" > build_image_tag.txt'
    - 'echo "$BUILD_IMAGE_NAME:latest" > build_image_latest.txt'
    
    # Create environment file with image info
    - |
      cat > build.env << EOF
      BUILD_IMAGE_TAG=$BUILD_IMAGE_TAG
      BUILD_IMAGE_NAME=$BUILD_IMAGE_NAME
      EOF
  artifacts:
    reports:
      dotenv: build.env
    paths:
      - build_image_tag.txt
      - build_image_latest.txt
    expire_in: 1 hour
  cache:
    key: "build-image-cache-$CI_COMMIT_REF_SLUG"
    paths:
      - .podman-cache/
    policy: pull-push

# =============================================================================
# STAGE 4: APK EXPORT - Extract and save APK as artifact
# =============================================================================
extract_apk:
  stage: apk_export
  image: quay.io/podman/stable:latest
  tags:
    - build-mergin-maps
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
  dependencies:
    - build_base_image
    - build_application_image
  before_script:
    - 'echo "📱 Starting APK extraction process..."'
    - 'echo "Using build image: $BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG"'
    # Initialize Podman for rootless operation
    - podman unshare --help > /dev/null || true
  script:
    # Create output directory
    - mkdir -p artifacts
    
    # Extract APK from build container
    - 'echo "📦 Extracting APK from container..."'
    - |
      podman run --rm \
        -v "$(pwd)/artifacts:/output:Z" \
        "$BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG" \
        sh -c "
          if [ -f '$APK_SOURCE_PATH' ]; then
            echo '✅ APK found, copying to output directory...'
            cp '$APK_SOURCE_PATH' '/output/$APK_ARTIFACT_NAME'
            ls -la '/output/$APK_ARTIFACT_NAME'
            echo '📊 APK size:' \$(du -h '/output/$APK_ARTIFACT_NAME' | cut -f1)
          else
            echo '❌ APK not found at expected location: $APK_SOURCE_PATH'
            echo '🔍 Available files in build directory:'
            find /var/www/mergin-maps/build -name '*.apk' -type f 2>/dev/null || echo 'No APK files found'
            exit 1
          fi
        "
    
    # Verify APK was extracted successfully
    - |
      if [ -f "artifacts/$APK_ARTIFACT_NAME" ]; then
        echo "✅ APK extracted successfully"
        echo "📊 APK details:"
        ls -la "artifacts/$APK_ARTIFACT_NAME"
        echo "📏 APK size: $(du -h "artifacts/$APK_ARTIFACT_NAME" | cut -f1)"
      else
        echo "❌ APK extraction failed"
        exit 1
      fi
    
    # Generate APK metadata
    - |
      cat > artifacts/apk_metadata.json << EOF
      {
        "project": "$CI_PROJECT_NAME",
        "branch": "$CI_COMMIT_REF_NAME",
        "commit": "$CI_COMMIT_SHA",
        "short_commit": "$CI_COMMIT_SHORT_SHA",
        "pipeline_id": "$CI_PIPELINE_ID",
        "build_date": "$(date -u +'%Y-%m-%dT%H:%M:%SZ')",
        "base_image_tag": "$BASE_IMAGE_NAME:$BASE_IMAGE_TAG",
        "build_image_tag": "$BUILD_IMAGE_NAME:$BUILD_IMAGE_TAG",
        "apk_name": "$APK_ARTIFACT_NAME",
        "apk_size": "$(du -b "artifacts/$APK_ARTIFACT_NAME" | cut -f1)",
        "container_runtime": "podman",
        "build_strategy": "two-stage"
      }
      EOF
    
    - 'echo "📋 APK metadata generated"'
    - 'cat artifacts/apk_metadata.json'
  artifacts:
    name: "mergin-maps-apk-$CI_COMMIT_SHORT_SHA"
    paths:
      - artifacts/$APK_ARTIFACT_NAME
      - artifacts/apk_metadata.json
    reports:
      # This makes the APK available as a downloadable artifact in GitLab UI
      dotenv: apk.env
    expire_in: 30 days
    when: always

# =============================================================================
# PIPELINE CONFIGURATION
# =============================================================================
# Cache configuration for better performance
cache:
  key: "mergin-maps-cache-$CI_COMMIT_REF_SLUG"
  paths:
    - .podman-cache/
  policy: pull-push

# Pipeline configuration
workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "web"
    - if: $CI_PIPELINE_SOURCE == "api"