#!/bin/bash
#
# Script to identify all assisted_service_9 images from multicluster-engine-index/index.json
# and run podman to check for nmstate libraries in /usr/lib64/
#
# The script converts registry.redhat.io to registry.stage.redhat.io for pre-GA testing
#

# Don't use set -e as we need to handle grep/podman exit codes gracefully
set -o pipefail

# Configuration
INDEX_FILE="${INDEX_FILE:-multicluster-engine-index/index.json}"
OUTPUT_FILE="${OUTPUT_FILE:-assisted-service-nmst-results.txt}"

# Registry replacement: use stage registry instead of production
SOURCE_REGISTRY="${SOURCE_REGISTRY:-registry.redhat.io}"
TARGET_REGISTRY="${TARGET_REGISTRY:-registry.stage.redhat.io}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

echo "=============================================="
echo "Assisted Service 9 - NMState Library Checker"
echo "=============================================="
echo ""
echo -e "${CYAN}Configuration:${NC}"
echo "  Index file: $INDEX_FILE"
echo "  Output file: $OUTPUT_FILE"
echo "  Source registry: $SOURCE_REGISTRY"
echo "  Target registry: $TARGET_REGISTRY"
echo ""

# Check if index file exists
if [[ ! -f "$INDEX_FILE" ]]; then
    echo -e "${RED}ERROR: Index file not found: $INDEX_FILE${NC}"
    exit 1
fi

# Extract unique assisted_service_9 images from index.json along with bundle names
echo -e "${BLUE}Extracting assisted_service_9 images from $INDEX_FILE...${NC}"

# Temporary file to store bundle-image pairs
TEMP_FILE=$(mktemp)
trap "rm -f $TEMP_FILE" EXIT

# Use jq to extract bundle name and assisted_service_9 image pairs
# Format: bundle_name|image
jq -r '
  select(.schema == "olm.bundle") |
  . as $bundle |
  .relatedImages[]? |
  select(.name == "assisted_service_9") |
  "\($bundle.name)|\(.image)"
' "$INDEX_FILE" 2>/dev/null | sort -u > "$TEMP_FILE"

# Alternative extraction method using grep/awk if jq method doesn't work well
if [[ ! -s "$TEMP_FILE" ]]; then
    echo -e "${YELLOW}Using alternative extraction method...${NC}"
    
    # Extract bundle names and their associated assisted_service_9 images
    awk '
    BEGIN { bundle_name = "" }
    /"schema": "olm.bundle"/ { in_bundle = 1 }
    in_bundle && /"name":/ && bundle_name == "" { 
        gsub(/.*"name": "/, ""); 
        gsub(/".*/, ""); 
        bundle_name = $0 
    }
    /"name": "assisted_service_9"/ { found_assisted = 1 }
    found_assisted && /"image":/ {
        gsub(/.*"image": "/, "");
        gsub(/".*/, "");
        if (bundle_name != "" && $0 != "") {
            print bundle_name "|" $0
        }
        found_assisted = 0
    }
    /^}$/ { 
        if (in_bundle) {
            bundle_name = ""
            in_bundle = 0
        }
    }
    ' "$INDEX_FILE" | sort -u > "$TEMP_FILE"
fi

# If still empty, fall back to simpler method without bundle names
if [[ ! -s "$TEMP_FILE" ]]; then
    echo -e "${YELLOW}Using simple extraction (without bundle names)...${NC}"
    grep -A1 '"name": "assisted_service_9"' "$INDEX_FILE" | \
        grep '"image":' | \
        sed 's/.*"image": "\([^"]*\)".*/UNKNOWN|\1/' | \
        sort -u > "$TEMP_FILE"
fi

# Convert registry.redhat.io to registry.stage.redhat.io
echo -e "${BLUE}Converting images from $SOURCE_REGISTRY to $TARGET_REGISTRY...${NC}"

# Read pairs and convert registries, storing in associative arrays
declare -A BUNDLE_FOR_IMAGE
declare -a IMAGES_ARRAY

while IFS='|' read -r bundle_name image_ref; do
    [[ -z "$image_ref" ]] && continue
    # Convert to stage registry
    stage_image=$(echo "$image_ref" | sed "s|${SOURCE_REGISTRY}|${TARGET_REGISTRY}|g")
    # Store bundle name for this image (use the first bundle if image appears in multiple)
    if [[ -z "${BUNDLE_FOR_IMAGE[$stage_image]:-}" ]]; then
        BUNDLE_FOR_IMAGE["$stage_image"]="$bundle_name"
        IMAGES_ARRAY+=("$stage_image")
    else
        # Append bundle name if different
        if [[ "${BUNDLE_FOR_IMAGE[$stage_image]}" != *"$bundle_name"* ]]; then
            BUNDLE_FOR_IMAGE["$stage_image"]="${BUNDLE_FOR_IMAGE[$stage_image]}, $bundle_name"
        fi
    fi
done < "$TEMP_FILE"

# Convert array to newline-separated string for compatibility
IMAGES=$(printf '%s\n' "${IMAGES_ARRAY[@]}")

# Count unique images
if [[ -z "$IMAGES" ]]; then
    echo -e "${RED}ERROR: No images found${NC}"
    exit 1
fi

IMAGE_COUNT=$(echo "$IMAGES" | wc -l | tr -d ' ')
echo -e "${GREEN}Found $IMAGE_COUNT unique assisted_service_9 images${NC}"
echo ""

# Show the images that will be processed
echo -e "${CYAN}Images to be processed (using $TARGET_REGISTRY):${NC}"
echo ""
preview_count=0
for img in "${IMAGES_ARRAY[@]}"; do
    preview_count=$((preview_count + 1))
    if [[ $preview_count -le 5 ]]; then
        bundle="${BUNDLE_FOR_IMAGE[$img]:-UNKNOWN}"
        echo -e "  ${YELLOW}$bundle${NC}"
        echo "    $img"
    fi
done
if [[ "$IMAGE_COUNT" -gt 5 ]]; then
    echo "  ... and $((IMAGE_COUNT - 5)) more"
fi
echo ""

echo -e "${BLUE}Starting image processing...${NC}"
echo ""

# Initialize results file
echo "# Assisted Service 9 - NMState Library Check Results" > "$OUTPUT_FILE"
echo "# Generated: $(date)" >> "$OUTPUT_FILE"
echo "# Index file: $INDEX_FILE" >> "$OUTPUT_FILE"
echo "# Source registry: $SOURCE_REGISTRY" >> "$OUTPUT_FILE"
echo "# Target registry: $TARGET_REGISTRY" >> "$OUTPUT_FILE"
echo "# Total unique images: $IMAGE_COUNT" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"

# Counter for progress
counter=0
found_count=0
not_found_count=0
error_count=0

# Process each image
while IFS= read -r image; do
    # Skip empty lines
    if [[ -z "$image" ]]; then
        continue
    fi
    
    counter=$((counter + 1))
    
    # Calculate the original image reference (for documentation)
    original_image=$(echo "$image" | sed "s|${TARGET_REGISTRY}|${SOURCE_REGISTRY}|g")
    
    # Get the bundle name(s) for this image
    bundle_name="${BUNDLE_FOR_IMAGE[$image]:-UNKNOWN}"
    
    echo -e "${BLUE}[$counter/$IMAGE_COUNT] Processing:${NC}"
    echo -e "  ${YELLOW}Bundle:${NC}   $bundle_name"
    echo -e "  ${CYAN}Original:${NC} $original_image"
    echo -e "  ${GREEN}Stage:${NC}    $image"
    echo ""
    
    # Log to file
    echo "========================================" >> "$OUTPUT_FILE"
    echo "Image [$counter/$IMAGE_COUNT]:" >> "$OUTPUT_FILE"
    echo "  Bundle:   $bundle_name" >> "$OUTPUT_FILE"
    echo "  Original: $original_image" >> "$OUTPUT_FILE"
    echo "  Stage:    $image" >> "$OUTPUT_FILE"
    echo "----------------------------------------" >> "$OUTPUT_FILE"
    
    # Run podman to check for nmstate libraries
    echo -e "${YELLOW}  Running: podman run --rm --entrypoint \"\" $image sh -c 'ls -la /usr/lib64/ | grep nmst'${NC}"
    
    # Run podman and capture output
    result=""
    exit_code=0
    result=$(podman run --rm --entrypoint "" "$image" sh -c 'ls -la /usr/lib64/ | grep nmst' 2>&1) || exit_code=$?
    
    if [[ $exit_code -eq 0 ]] && [[ -n "$result" ]]; then
        echo -e "${GREEN}  Found nmstate libraries:${NC}"
        echo "$result" | while read -r line; do
            echo "    $line"
        done
        echo "RESULT: FOUND" >> "$OUTPUT_FILE"
        echo "$result" >> "$OUTPUT_FILE"
        found_count=$((found_count + 1))
    elif [[ $exit_code -eq 1 ]] && [[ -z "$result" || "$result" == "" ]]; then
        # grep returns exit code 1 when no matches found
        echo -e "${YELLOW}  No nmstate libraries found${NC}"
        echo "RESULT: NOT FOUND" >> "$OUTPUT_FILE"
        not_found_count=$((not_found_count + 1))
    elif echo "$result" | grep -qiE "error|failed|unable|not found|manifest unknown"; then
        echo -e "${RED}  Error running container:${NC}"
        echo "$result" | head -5 | while read -r line; do
            echo "    $line"
        done
        echo "RESULT: ERROR" >> "$OUTPUT_FILE"
        echo "$result" >> "$OUTPUT_FILE"
        error_count=$((error_count + 1))
    else
        # Default: no matches found
        echo -e "${YELLOW}  No nmstate libraries found${NC}"
        echo "RESULT: NOT FOUND" >> "$OUTPUT_FILE"
        if [[ -n "$result" ]]; then
            echo "$result" >> "$OUTPUT_FILE"
        fi
        not_found_count=$((not_found_count + 1))
    fi
    
    echo "" >> "$OUTPUT_FILE"
    echo ""
    
done <<< "$IMAGES"

# Summary
echo ""
echo "=============================================="
echo "Summary"
echo "=============================================="
echo -e "Total images processed: ${BLUE}$counter${NC}"
echo -e "Images with nmstate libs: ${GREEN}$found_count${NC}"
echo -e "Images without nmstate libs: ${YELLOW}$not_found_count${NC}"
echo -e "Errors: ${RED}$error_count${NC}"
echo ""
echo "Results saved to: $OUTPUT_FILE"

# Also append summary to results file
echo "" >> "$OUTPUT_FILE"
echo "=============================================" >> "$OUTPUT_FILE"
echo "SUMMARY" >> "$OUTPUT_FILE"
echo "=============================================" >> "$OUTPUT_FILE"
echo "Total images processed: $counter" >> "$OUTPUT_FILE"
echo "Images with nmstate libs: $found_count" >> "$OUTPUT_FILE"
echo "Images without nmstate libs: $not_found_count" >> "$OUTPUT_FILE"
echo "Errors: $error_count" >> "$OUTPUT_FILE"
