name: Resolve Docker Version
description: |
  Resolves and validates Docker-compatible SemVer versions for container builds with comprehensive security.

  Security Features:
  - Command injection protection
  - Input sanitization and validation
  - Docker tag character restrictions
  - Length limits and boundary checks
  - Safe branch name handling

  Supports multiple modes: release, manual override, branch auto-detection, and experimental timestamped versions.

inputs:
  version:
    description: "Explicit version (SemVer only, e.g., 1.2.3-beta). If provided, this version is used directly. If empty, version is auto-generated from branch name."
    required: false
  current_branch:
    description: "Current branch name for auto-detection"
    required: true
  experimental_mode:
    description: "Enable experimental mode with timestamp-based versions"
    required: false
    default: "false"

outputs:
  version:
    description: "Resolved Docker-compatible SemVer version"
    value: ${{ steps.resolve.outputs.version }}
  source:
    description: "Source of version (release|override|branch)"
    value: ${{ steps.resolve.outputs.source }}
  normalized:
    description: "Whether the version was normalized (true/false)"
    value: ${{ steps.resolve.outputs.normalized }}

runs:
  using: "composite"
  steps:
    - name: Resolve and validate Docker version
      id: resolve
      shell: bash
      env:
        EXPLICIT_VERSION: ${{ inputs.version }}
        CURRENT_BRANCH: ${{ inputs.current_branch }}
        EXPERIMENTAL_MODE: ${{ inputs.experimental_mode }}
      run: |
        set -euo pipefail

        # Function to validate SemVer format (Docker-compatible, no '+' build metadata)
        validate_semver() {
          local version="$1"
          local context="$2"
          
          if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
            echo "ERROR: Invalid $context format. Must be semver without build metadata (e.g., 1.2.3, 1.2.3-alpha)"
            echo "Provided: $version"
            echo "Note: Docker tags cannot contain '+' characters. Use prerelease identifiers instead."
            exit 1
          fi
        }

        # Function to generate branch-based version
        generate_branch_version() {
          local branch="$1"
          local use_timestamp="${2:-true}"
          local timestamp
          
          if [[ "$use_timestamp" == "true" ]]; then
            timestamp=$(date +%s)
          else
            timestamp=""
          fi
          
          # Sanitize branch name for Docker compatibility
          local sanitized_branch=$(echo "$branch" | sed 's/[^a-zA-Z0-9.-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
          
          # Additional safety: truncate if too long (reserve space for prefix and timestamp)
          if (( ${#sanitized_branch} > 80 )); then
            sanitized_branch="${sanitized_branch:0:80}"
            echo "INFO: Branch name truncated for Docker compatibility" >&2
          fi
          local version
          
          # Generate version based on branch name (unified approach)
          # All branches get alpha versions with sanitized branch name
          if [[ -n "$timestamp" ]]; then
            version="0.0.0-alpha-$sanitized_branch-$timestamp"
            echo "INFO: Branch '$branch' detected - alpha version: $version" >&2
          else
            version="0.0.0-alpha-$sanitized_branch"
            echo "INFO: Branch '$branch' detected - alpha version: $version" >&2
          fi
          
          echo "$version"
        }


        # Input validation and sanitization
        if [[ -z "$CURRENT_BRANCH" ]]; then
          echo "ERROR: current_branch input is required"
          exit 1
        fi

        # Security: Validate inputs to prevent command injection
        # Use grep to check for dangerous characters (more reliable than bash regex)
        validate_input() {
          local input="$1"
          local name="$2"
          
          # Check for dangerous characters using grep
          if echo "$input" | grep -q '[;|&`$(){}\\[:space:]]'; then
            echo "ERROR: $name contains potentially dangerous characters: $input"
            echo "Input should only contain letters, numbers, hyphens, underscores, dots, and forward slashes"
            return 1
          fi
          
          return 0
        }

        # Validate current branch
        if ! validate_input "$CURRENT_BRANCH" "Branch name"; then
          exit 1
        fi

        # Validate explicit version if provided
        if [[ -n "$EXPLICIT_VERSION" ]] && ! validate_input "$EXPLICIT_VERSION" "Explicit version"; then
          exit 1
        fi

        # Main resolution logic (ultra-simplified)
        NORMALIZED="false"

        if [[ -n "$EXPLICIT_VERSION" ]]; then
          # Use provided explicit version (from either workflow_call or manual input)
          validate_semver "$EXPLICIT_VERSION" "explicit version"
          
          # Normalize to lowercase for Docker/ECR compatibility
          RESOLVED_VERSION="${EXPLICIT_VERSION,,}"
          if [[ "$EXPLICIT_VERSION" != "$RESOLVED_VERSION" ]]; then
            NORMALIZED="true"
            echo "INFO: Original version contained uppercase characters, normalized: $EXPLICIT_VERSION -> $RESOLVED_VERSION"
          fi
          
          SOURCE="explicit"
          echo "INFO: Using explicit version: $RESOLVED_VERSION"
          
        else
          # Auto-generate version from branch name
          if [[ "$EXPERIMENTAL_MODE" == "true" ]]; then
            # Use timestamped version generation
            echo "INFO: Experimental mode: generating timestamped version from branch: $CURRENT_BRANCH"
            RESOLVED_VERSION=$(generate_branch_version "$CURRENT_BRANCH" "true")
            SOURCE="experimental"
          else
            # Standard branch version (no timestamp)
            echo "INFO: Auto-detecting version from branch: $CURRENT_BRANCH"
            RESOLVED_VERSION=$(generate_branch_version "$CURRENT_BRANCH" "false")
            SOURCE="branch"
          fi
          echo "Generated version: $RESOLVED_VERSION"
        fi

        # Final validation - ensure result is valid Docker tag
        if [[ -z "$RESOLVED_VERSION" ]]; then
          echo "ERROR: Failed to resolve version"
          exit 1
        fi

        if (( ${#RESOLVED_VERSION} > 128 )); then
          echo "ERROR: Version must be at most 128 characters (Docker limitation)"
          echo "Generated version: $RESOLVED_VERSION (${#RESOLVED_VERSION} chars)"
          exit 1
        fi

        if [[ ! "$RESOLVED_VERSION" =~ ^[a-z0-9._-]+$ ]]; then
          echo "ERROR: Version contains invalid characters for Docker tags"
          echo "Version: $RESOLVED_VERSION"
          exit 1
        fi

        if [[ "$RESOLVED_VERSION" =~ ^[.-] || "$RESOLVED_VERSION" =~ [.-]$ ]]; then
          echo "ERROR: Version must not start or end with '.' or '-'"
          echo "Version: $RESOLVED_VERSION"
          exit 1
        fi

        # Output results
        echo "SUCCESS: Resolved Docker version: $RESOLVED_VERSION (source: $SOURCE)"
        echo "version=$RESOLVED_VERSION" >> $GITHUB_OUTPUT
        echo "source=$SOURCE" >> $GITHUB_OUTPUT
        echo "normalized=$NORMALIZED" >> $GITHUB_OUTPUT
