#!/bin/bash
# Script to build and deploy Python package to PyPI
#
# IMPORTANT: This script is for maintainers who need to publish the client library to PyPI.
# It handles the entire build and deployment process, including:
# - Setting up a clean build environment
# - Building both wheel and source distribution packages
# - Checking package validity with twine
# - Supporting uploads to TestPyPI for validation
# - Publishing to the main PyPI repository
#
# The script checks for proper authentication (~/.pypirc) and provides detailed
# guidance if the setup is incomplete.
#
# Usage:
#   ./run_pypi_deploy.sh

set -e  # Exit immediately if a command exits with a non-zero status
set -u  # Treat unset variables as an error
set -o pipefail  # Return value of a pipeline is the value of the last command to exit with non-zero status

# --- Configuration ---
# Get the directory of this script (which is assumed to be the project root: python/)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYPIRC_PATH="$HOME/.pypirc"
VENV_DIR=".venv_pypi_deploy"
PYTHON_INTERPRETER="python3"

# --- Script Start ---
echo "INFO: Starting PyPI deployment process..."

# Check for .pypirc file
if [ ! -f "$PYPIRC_PATH" ]; then
    echo "ERROR: $PYPIRC_PATH file not found!"
    echo ""
    echo "To fix this, create a .pypirc file in your home directory with the following content:"
    echo ""
    echo "[distutils]"
    echo "index-servers ="
    echo "    pypi"
    echo "    testpypi"
    echo ""
    echo "[pypi]"
    echo "# Basic auth option:"
    echo "username = your_username"
    echo "password = your_password"
    echo "# Or token auth option (recommended):"
    echo "# username = __token__"
    echo "# password = pypi-..."
    echo ""
    echo "[testpypi]"
    echo "repository = https://test.pypi.org/legacy/"
    echo "# Basic auth option:"
    echo "username = your_username"
    echo "password = your_password"
    echo "# Or token auth option (recommended):"
    echo "# username = __token__"
    echo "# password = pypi-..."
    echo ""
    echo "Replace 'your_username' and 'your_password' with your actual PyPI credentials."
    echo "For better security, we strongly recommend using an API token instead of your password."
    echo "Learn more: https://pypi.org/help/#apitoken"
    exit 1
fi

# Check if the content of .pypirc is valid
MISSING_SECTIONS=""
if ! grep -q "\[pypi\]" "$PYPIRC_PATH"; then
    MISSING_SECTIONS="$MISSING_SECTIONS [pypi]"
fi
if ! grep -q "\[testpypi\]" "$PYPIRC_PATH"; then
    MISSING_SECTIONS="$MISSING_SECTIONS [testpypi]"
fi
if ! grep -q "username" "$PYPIRC_PATH" && ! grep -q "password" "$PYPIRC_PATH" && ! grep -q "token" "$PYPIRC_PATH"; then
    MISSING_SECTIONS="$MISSING_SECTIONS credentials(username/password/token)"
fi

if [ -n "$MISSING_SECTIONS" ]; then
    echo "WARNING: Your $PYPIRC_PATH file seems to be missing:$MISSING_SECTIONS"
    echo "This might cause authentication issues when uploading to PyPI."
    echo "Please check the file format using the example below:"
    echo ""
    echo "[distutils]"
    echo "index-servers ="
    echo "    pypi"
    echo "    testpypi"
    echo ""
    echo "[pypi]"
    echo "# Basic auth"
    echo "username = your_username"
    echo "password = your_password"
    echo "# Or token auth"
    echo "# username = __token__"
    echo "# password = pypi-..."
    echo ""
    echo "[testpypi]"
    echo "repository = https://test.pypi.org/legacy/"
    echo "# Basic auth"
    echo "username = your_username"
    echo "password = your_password"
    echo "# Or token auth"
    echo "# username = __token__"
    echo "# password = pypi-..."
    echo ""
    read -p "Do you want to continue anyway? (y/n) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
fi

# Ensure we're in the project root
cd "$SCRIPT_DIR"

# We'll install the necessary Python modules in the venv rather than
# requiring them to be installed globally

# Create a virtual environment for the build if it doesn't exist
if [ ! -d "$VENV_DIR" ]; then
    echo "INFO: Creating virtual environment in '$VENV_DIR'..."
    if command -v uv &> /dev/null; then
        uv venv "$VENV_DIR" --python "$PYTHON_INTERPRETER"
    else
        $PYTHON_INTERPRETER -m venv "$VENV_DIR"
    fi
fi

# Determine the Python executable path within the venv
if [ -f "$VENV_DIR/bin/python" ]; then
    PYTHON_IN_VENV="$VENV_DIR/bin/python"
elif [ -f "$VENV_DIR/Scripts/python.exe" ]; then  # Windows path
    PYTHON_IN_VENV="$VENV_DIR/Scripts/python.exe"
else
    echo "ERROR: Python executable not found in virtual environment path"
    exit 1
fi

# Install required packages in the venv
echo "INFO: Installing build dependencies..."
if command -v uv &> /dev/null; then
    # Use uv if available
    uv pip install --python "$PYTHON_IN_VENV" --upgrade build twine
else
    # Fall back to pip if uv is not available
    "$PYTHON_IN_VENV" -m pip install --upgrade pip
    "$PYTHON_IN_VENV" -m pip install --upgrade build twine
fi

# Clean the dist directory if it exists
if [ -d "dist" ]; then
    echo "INFO: Cleaning existing distribution files..."
    rm -rf dist/*
fi

# Build the package
echo "INFO: Building the package..."
# Try to use the build module, install it if it's not found
if ! "$PYTHON_IN_VENV" -c "import build" &> /dev/null; then
    echo "WARNING: Python build module not found, installing it now..."
    if command -v uv &> /dev/null; then
        uv pip install --python "$PYTHON_IN_VENV" build
    else
        "$PYTHON_IN_VENV" -m pip install build
    fi
fi

"$PYTHON_IN_VENV" -m build

# Check the built distribution
echo "INFO: Checking the distribution files..."
# Make sure twine is available
if ! "$PYTHON_IN_VENV" -c "import twine" &> /dev/null; then
    echo "WARNING: Python twine module not found, installing it now..."
    if command -v uv &> /dev/null; then
        uv pip install --python "$PYTHON_IN_VENV" twine
    else
        "$PYTHON_IN_VENV" -m pip install twine
    fi
fi

"$PYTHON_IN_VENV" -m twine check dist/*
if [ $? -ne 0 ]; then
    echo "ERROR: Twine check failed. Please fix the issues before uploading."
    exit 1
fi

# Ask user if they want to upload to TestPyPI first
read -p "Do you want to upload to TestPyPI first for testing? (recommended) (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "INFO: Uploading to TestPyPI..."
    # Ensure twine is available
    if ! "$PYTHON_IN_VENV" -c "import twine" &> /dev/null; then
        echo "WARNING: Python twine module not found, installing it now..."
        if command -v uv &> /dev/null; then
            uv pip install --python "$PYTHON_IN_VENV" twine
        else
            "$PYTHON_IN_VENV" -m pip install twine
        fi
    fi

    "$PYTHON_IN_VENV" -m twine upload --config-file "$PYPIRC_PATH" --repository testpypi dist/*
    
    if [ $? -eq 0 ]; then
        echo "SUCCESS: Package uploaded to TestPyPI."
        echo "You can install it with one of the following methods:"
        echo "  pip install --index-url https://test.pypi.org/simple/ goodmem-client"
        if command -v uv &> /dev/null; then
            echo "  uv pip install --index-url https://test.pypi.org/simple/ goodmem-client"
        fi
    else
        echo "ERROR: Failed to upload to TestPyPI."
        exit 1
    fi
    
    # Ask if they want to continue to real PyPI
    read -p "Do you want to continue and upload to the real PyPI? (y/n) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "INFO: Deployment to real PyPI cancelled. Package is only on TestPyPI."
        exit 0
    fi
fi

# Upload to the real PyPI
echo "INFO: Uploading to PyPI..."
"$PYTHON_IN_VENV" -m twine upload --config-file "$PYPIRC_PATH" dist/*

if [ $? -eq 0 ]; then
    echo "SUCCESS: Package uploaded to PyPI!"
    echo "It can be installed with one of the following methods:"
    echo "  pip install goodmem-client"
    if command -v uv &> /dev/null; then
        echo "  uv pip install goodmem-client"
    fi
else
    echo "ERROR: Failed to upload to PyPI."
    exit 1
fi

echo "INFO: PyPI deployment process completed successfully."