#!/bin/bash
# start sprinkler in virtual environment
# WF 2024-08-30

# Exit immediately if a command exits with a non-zero status
set -e

# Color definitions
blue='\033[0;34m'
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[1;33m'
endColor='\033[0m'

# Define the name of the virtual environment
VENV_NAME="sprinkler_venv"

# Function to display colored messages
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

# Function to display errors
error() {
  local l_msg="$1"
  color_msg $red "Error:" 1>&2
  color_msg $red "\t$l_msg" 1>&2
  exit 1
}

# Function to display warnings
warning() {
  local l_msg="$1"
  color_msg $yellow "⚠️  Warning: $l_msg"
}

# Function to display positive messages
positive() {
  local l_msg="$1"
  color_msg $green "✅ $l_msg"
}

# Function to display usage information
usage() {
  echo "Usage: $0 [OPTIONS]"
  echo "Options:"
  echo "  -h, --help         Show this help message"
  echo "  -a, --activate     Activate the virtual environment"
  echo "  -d, --debug        Enable debug output (set -x)"
  echo "  -i, --install      Install the project in a virtual environment"
  echo "  -s, --start        Start the sprinkler system"
  echo "  --version          Show version information"
  exit 1
}

# Function to activate the virtual environment
activate_venv() {
  # Check if the virtual environment exists
  if [ ! -d "$VENV_NAME" ]; then
    error "Virtual environment '$VENV_NAME' does not exist. Please run the install option first."
  fi

  color_msg $blue "Activating virtual environment..."
  source $VENV_NAME/bin/activate
  positive "Virtual environment activated."
}

# Function to install the project
install_project() {
  # Check if virtual environment already exists
  if [ -d "$VENV_NAME" ]; then
    warning "Virtual environment '$VENV_NAME' already exists."
    read -p "Do you want to remove it and create a new one? (y/n) " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
      color_msg $blue "Removing existing virtual environment..."
      rm -rf $VENV_NAME
      positive "Existing virtual environment removed."
    else
      positive "Using existing virtual environment."
    fi
  fi

  # Create virtual environment if it doesn't exist
  if [ ! -d "$VENV_NAME" ]; then
    color_msg $blue "Creating virtual environment '$VENV_NAME'..."
    python3 -m venv $VENV_NAME
    positive "Virtual environment created."
  fi

  # Activate virtual environment
  color_msg $blue "Activating virtual environment..."
  source $VENV_NAME/bin/activate
  positive "Virtual environment activated."

  # Upgrade pip
  color_msg $blue "Upgrading pip..."
  pip install --upgrade pip
  positive "Pip upgraded."

  # Install RPi.GPIO package
	color_msg $blue "Installing RPi.GPIO..."
	pip install RPi.GPIO
	positive "RPi.GPIO installed."

  # Install the project
  color_msg $blue "Installing the project..."
  pip install .
  positive "Project installed."

  warning "To activate this virtual environment in the future, run:"
  echo "source $VENV_NAME/bin/activate"

  # Deactivate virtual environment
  deactivate
  positive "Virtual environment deactivated. Setup complete!"
}

# Function to start the sprinkler system
start_sprinkler() {
  # Activate virtual environment
  color_msg $blue "Activating virtual environment..."
  source $VENV_NAME/bin/activate
  positive "Virtual environment activated."

  # Start the sprinkler system
  color_msg $blue "Starting the sprinkler system..."
  sprinkler -s --host 0.0.0.0
  positive "Sprinkler system started!"

  # Deactivate virtual environment
  deactivate
  positive "Virtual environment deactivated."
}

# Parse command line arguments and execute corresponding functions
while [[ $# -gt 0 ]]; do
  case $1 in
    -h|--help) usage ;;
    -a|--activate) activate_venv; exit 0 ;;  # This line handles the activation
    -d|--debug) set -x ;;
    -i|--install) install_project; exit 0 ;;
    -s|--start) start_sprinkler; exit 0 ;;
    --version) echo "Version: 1.0.0"; exit 0 ;;
    *) error "Unknown option: $1" ;;
  esac
  shift
done

# If no arguments were provided, show usage
usage
