#!/bin/bash
# ============================================================================
# VEOX Client — Build and Publish to PyPI
# ============================================================================
# Builds and optionally publishes the VEOX Evolution Client.
#
# Usage:
#   bash Public/veox_client/build_and_publish_client.sh [OPTIONS]
#
# Options:
#   -h, --help       Show this help message and exit
#   --build          Build the Python package (sdist & wheel)
#   --publish        Publish the built package to PyPI
#   -y, --yes        Skip interactive confirmation prompts
# ============================================================================

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

usage() {
    cat <<EOF
============================================================================
VEOX Client — Build and Publish to PyPI
============================================================================
Builds and optionally publishes the VEOX Evolution Client.

Usage:
  bash Public/veox_client/build_and_publish_client.sh [OPTIONS]

Options:
  -h, --help       Show this help message and exit
  --build          Build the Python package (sdist & wheel)
  --publish        Publish the built package to PyPI
  --test           Publish to TestPyPI instead of production PyPI
  -y, --yes        Skip interactive confirmation prompts
  --bump-version TYPE  Auto-bump version before building ('patch', 'minor', 'major')
============================================================================
EOF
}

DO_BUILD=false
DO_PUSH=false
DO_TEST=false
SKIP_PROMPT=false
BUMP_VERSION_TYPE=""

while [[ $# -gt 0 ]]; do
  case $1 in
    -h|--help)
      usage
      exit 0
      ;;
    --build)
      DO_BUILD=true
      shift 1
      ;;
    --publish)
      DO_PUSH=true
      shift 1
      ;;
    --test)
      DO_TEST=true
      shift 1
      ;;
    -y|--yes)
      SKIP_PROMPT=true
      shift 1
      ;;
    --bump-version)
      BUMP_VERSION_TYPE="$2"
      if [[ "$BUMP_VERSION_TYPE" != "patch" && "$BUMP_VERSION_TYPE" != "minor" && "$BUMP_VERSION_TYPE" != "major" ]]; then
          echo "❌ ERROR: --bump-version requires 'patch', 'minor', or 'major'."
          echo ""
          usage
          exit 1
      fi
      shift 2
      ;;
    *)
      echo "❌ ERROR: Unknown argument: $1"
      echo ""
      usage
      exit 1
      ;;
  esac
done

if [[ "$DO_BUILD" == false && "$DO_PUSH" == false ]]; then
    echo "❌ ERROR: No action specified. Use --build and/or --publish."
    echo ""
    usage
    exit 1
fi

if [[ -z "${VIRTUAL_ENV:-}" ]]; then
    echo ""
    echo "╔═════════════════════════════════════════════════════════════════════════════════════╗"
    echo "║   ⚠️ System Python Warning                                                          ║"
    echo "╠═════════════════════════════════════════════════════════════════════════════════════╣"
    echo "║  You do not appear to be inside a Python virtual environment (venv).                ║"
    echo "║  Installing dependencies globally may cause conflicts or permission errors.         ║"
    echo "╚═════════════════════════════════════════════════════════════════════════════════════╝"
    echo ""
    
    if [[ "$SKIP_PROMPT" == false ]]; then
        read -p "Are you sure you want to proceed using the system Python environment? (y/N) " -n 1 -r
        echo ""
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo "Operation cancelled by user."
            exit 1
        fi
        echo ""
    else
        echo "⚠️  Proceeding with system Python automatically (--yes)."
        echo ""
    fi
fi


if command -v python >/dev/null 2>&1; then
    PYTHON_CMD="python"
elif command -v python3 >/dev/null 2>&1; then
    PYTHON_CMD="python3"
else
    echo "❌ ERROR: Neither 'python' nor 'python3' was found in PATH."
    echo "Please install Python to build and publish this package."
    exit 1
fi

if command -v pip >/dev/null 2>&1; then
    PIP_CMD="pip"
elif command -v pip3 >/dev/null 2>&1; then
    PIP_CMD="pip3"
else
    echo "❌ ERROR: Neither 'pip' nor 'pip3' was found in PATH."
    echo "Please install pip to build and publish this package."
    exit 1
fi

confirm() {
    local prompt_message="$1"
    if [[ "$SKIP_PROMPT" == true ]]; then
        return 0
    fi
    read -p "$prompt_message (y/N) " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "Operation cancelled by user."
        exit 1
    fi
}

TARGET_REPO="PyPI (Production)"
if [[ "$DO_TEST" == true ]]; then
    TARGET_REPO="TestPyPI (Staging)"
fi

echo "╔══════════════════════════════════════════════════╗"
echo "║   🚀 VEOX Client — Build & Publish               ║"
echo "╠══════════════════════════════════════════════════╣"
if [[ "$DO_BUILD" == true ]]; then
echo "║  Build:      Yes (sdist & wheel)                 ║"
else
echo "║  Build:      No                                  ║"
fi
if [[ "$DO_PUSH" == true ]]; then
echo "║  Publish:    Yes -> ${TARGET_REPO}               ║"
else
echo "║  Publish:    No                                  ║"
fi
echo "╚══════════════════════════════════════════════════╝"
echo ""

if [[ "$DO_BUILD" == true || "$DO_PUSH" == true ]]; then
    # Version Bump
    if [[ -f "pyproject.toml" ]]; then
        CURRENT_VERSION=$(grep -E '^version\s*=' pyproject.toml | tr -d ' "' | cut -d'=' -f2)
        
        NEW_VERSION=""
        if [[ -n "$BUMP_VERSION_TYPE" ]]; then
            # Parse MAJOR.MINOR.PATCH
            IFS='.' read -r major minor patch <<< "$CURRENT_VERSION"
            
            # Handle empty values (e.g. if parsing failed) gracefully just in case
            major=${major:-0}
            minor=${minor:-0}
            patch=${patch:-0}
            
            if [[ "$BUMP_VERSION_TYPE" == "major" ]]; then
                major=$((major + 1))
                minor=0
                patch=0
            elif [[ "$BUMP_VERSION_TYPE" == "minor" ]]; then
                minor=$((minor + 1))
                patch=0
            elif [[ "$BUMP_VERSION_TYPE" == "patch" ]]; then
                patch=$((patch + 1))
            fi
            NEW_VERSION="${major}.${minor}.${patch}"
            echo "Auto-bumping version $CURRENT_VERSION -> $NEW_VERSION ($BUMP_VERSION_TYPE)"
        elif [[ "$SKIP_PROMPT" == false ]]; then
            echo "Current version in pyproject.toml: $CURRENT_VERSION"
            while true; do
                read -p "Enter new version (or press Enter to keep '$CURRENT_VERSION'): " USER_INPUT
                
                # If they pressed enter, skip validation and keep current
                if [[ -z "$USER_INPUT" || "$USER_INPUT" == "$CURRENT_VERSION" ]]; then
                    break
                fi
                
                # Limit length to 50 characters
                if [[ ${#USER_INPUT} -gt 50 ]]; then
                    echo ""
                    echo "╔═════════════════════════════════════════════════════════════════════════════╗"
                    echo "║   ⚠️ Invalid Version Format                                                 ║"
                    echo "╠═════════════════════════════════════════════════════════════════════════════╣"
                    echo "║  Version number must be 50 characters or fewer.                             ║"
                    echo "╚═════════════════════════════════════════════════════════════════════════════╝"
                    echo ""
                    continue
                fi
                
                # Validate semantic formatting
                # Rules:
                # 1. Must begin with major.minor.patch numeric-only
                # 2. After semantic version, can have dashes, alphanumeric, underscore, period
                if ! [[ "$USER_INPUT" =~ ^[0-9]+\.[0-9]+\.[0-9]+[-_.]?[a-zA-Z0-9_\.-]*$ ]]; then
                    echo ""
                    echo "╔═════════════════════════════════════════════════════════════════════════════╗"
                    echo "║   ⚠️ Invalid Version Format                                                 ║"
                    echo "╠═════════════════════════════════════════════════════════════════════════════╣"
                    echo "║  Must begin with major.minor.patch formatting (numeric only).               ║"
                    echo "║  Optionally followed by dashes, alphanumeric, underscores, or periods.      ║"
                    echo "║                                                                             ║"
                    echo "║  Examples:                                                                  ║"
                    echo "║    - 1.0.2                                                                  ║"
                    echo "║    - 1.0.2-alpha.1                                                          ║"
                    echo "║    - 2.4.0_rc2                                                              ║"
                    echo "╚═════════════════════════════════════════════════════════════════════════════╝"
                    echo ""
                    continue
                fi
                
                # Validation passed
                NEW_VERSION="$USER_INPUT"
                break
            done
        fi

        if [[ -n "$NEW_VERSION" && "$NEW_VERSION" != "$CURRENT_VERSION" ]]; then
            # Using basic sed for portability 
            sed -i.bak "s/^version = \"$CURRENT_VERSION\"/version = \"$NEW_VERSION\"/" pyproject.toml
            rm -f pyproject.toml.bak
            echo "✅ Updated pyproject.toml to version $NEW_VERSION"
            echo ""
        fi
    fi
fi

if [[ "$DO_BUILD" == true ]]; then
  confirm "Proceed with building the package?"
  
  echo "🔧 Preparing build environment..."
  echo "Wiping old artifacts from dist/..."
  rm -rf dist/
  
  echo "Checking build dependencies..."
  if ! "$PYTHON_CMD" -m build --version >/dev/null 2>&1; then
      echo "Installing 'build' package..."
      "$PIP_CMD" install --upgrade pip build
  fi
  
  echo "🔧 Building the package..."
  echo ""
  "$PYTHON_CMD" -m build
  
  echo ""
  echo "✅ Build Complete!"
  echo ""
fi

if [[ "$DO_PUSH" == true ]]; then
  echo "Checking publish dependencies..."
  if ! "$PYTHON_CMD" -m twine --version >/dev/null 2>&1; then
      echo "Installing 'twine' package..."
      "$PIP_CMD" install --upgrade pip twine
  fi

  # 1. Check if dist/ exists and has files
  shopt -s nullglob
  FILES=(dist/*)
  shopt -u nullglob
  
  if [[ ${#FILES[@]} -eq 0 ]]; then
      echo "❌ ERROR: No files found in dist/ to publish."
      echo "Please run this script with --build first, or ensure compiled artifacts exist."
      exit 1
  fi

  # 2. Preview the exact payload
  echo "📦 The following artifacts are queued for upload to ${TARGET_REPO}:"
  for f in "${FILES[@]}"; do
      echo "  - $(basename "$f")"
  done
  echo ""

  confirm "Proceed with publishing to ${TARGET_REPO}?"
  
  echo "🚀 Publishing package via Twine API..."
  echo "(Make sure you have your PyPI token ready if not configured in .pypirc)"
  echo ""
  
  TWINE_ARGS=("upload" "--verbose")
  if [[ "$DO_TEST" == true ]]; then
      TWINE_ARGS+=("--repository" "testpypi")
  fi
  TWINE_ARGS+=("dist/*")
  
  # Capture twine execution
  set +e
  TWINE_OUTPUT=$("$PYTHON_CMD" -m twine "${TWINE_ARGS[@]}" 2>&1)
  TWINE_EXIT_CODE=$?
  set -e
  
  echo "$TWINE_OUTPUT"
  
  if [ $TWINE_EXIT_CODE -ne 0 ]; then
    echo ""
    echo "╔═════════════════════════════════════════════════════════════════════════════════════╗"
    echo "║   ❌ Publish FAILED                                                                 ║"
    echo "╠═════════════════════════════════════════════════════════════════════════════════════╣"
    echo "║  Twine encountered an error while uploading the distribution.                       ║"
    
    if echo "$TWINE_OUTPUT" | grep -q "File already exists"; then
        echo "║                                                                                     ║"
        echo "║  ⚠️  CAUSE: File Already Exists on PyPI                                              ║"
        echo "║  You cannot publish over an existing version number.                                ║"
        echo "║                                                                                     ║"
        echo "║  🛠️  FIX:                                                                            ║"
        echo "║  1. Update 'version = \"...\"' in pyproject.toml                                      ║"
        echo "║  2. Optionally clear old builds: rm -rf dist/                                       ║"
        echo "║  3. Re-run this script                                                              ║"
    fi
    
    echo "╚═════════════════════════════════════════════════════════════════════════════════════╝"
    echo ""
    exit 1
  fi
  
  echo ""
  echo "✅ Publish Complete!"
fi