#!/bin/bash
# Webhook deployment script
# This script is triggered by the webhook receiver when a push event is received

set -e

# Configuration
APP_DIR="/app"                                         # Application directory
REPO_URL="https://git.d-popov.com/popov/mwitnessing.git" # Git repository URL
GIT_USERNAME="${GIT_USERNAME:-deploy}"                 # Git username
GIT_PASSWORD="${GIT_PASSWORD:-}"                       # Git password
DOCKER_COMPOSE_FILE="${DOCKER_COMPOSE_FILE:-_deploy/standard-docker-compose.yml}" # Docker Compose file
LOG_FILE="${LOG_FILE:-/app/logs/webhook-deploy.log}"   # Log file

# Create log directory if it doesn't exist
mkdir -p "$(dirname "$LOG_FILE")"

# Function to log messages
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Get the branch name from the first argument or use main as default
BRANCH="${1:-main}"
log "Starting deployment for branch: $BRANCH"

# Create a temporary directory for the Git clone
TEMP_DIR=$(mktemp -d)
log "Using temporary directory: $TEMP_DIR"

# Clean up function to remove the temporary directory on exit
cleanup() {
  log "Cleaning up temporary directory"
  rm -rf "$TEMP_DIR"
}
trap cleanup EXIT

# Clone the repository
log "Cloning repository: $REPO_URL (branch: $BRANCH)"
if [ -n "$GIT_PASSWORD" ]; then
  # Use authentication with username and password
  AUTH_URL="${REPO_URL/https:\/\//https:\/\/$GIT_USERNAME:$GIT_PASSWORD@}"
  git clone -b "$BRANCH" --depth 1 "$AUTH_URL" "$TEMP_DIR"
else
  # Use authentication with SSH keys
  git clone -b "$BRANCH" --depth 1 "$REPO_URL" "$TEMP_DIR"
fi

# Navigate to the cloned repository
cd "$TEMP_DIR"

# Backup important directories
log "Backing up important directories"
mkdir -p "/tmp/webhook_backup/permits" "/tmp/webhook_backup/uploads"

if [ -d "$APP_DIR/public/content/permits" ]; then
  cp -r "$APP_DIR/public/content/permits/." "/tmp/webhook_backup/permits/"
  log "Permits directory backed up"
fi

if [ -d "$APP_DIR/public/content/uploads" ]; then
  cp -r "$APP_DIR/public/content/uploads/." "/tmp/webhook_backup/uploads/"
  log "Uploads directory backed up"
fi

# Check if we should rebuild the Docker image
REBUILD=0
if [ -f "$TEMP_DIR/package.json" ] && [ -f "$APP_DIR/package.json" ]; then
  if ! cmp -s "$TEMP_DIR/package.json" "$APP_DIR/package.json"; then
    log "package.json has changed, triggering full rebuild"
    REBUILD=1
  elif [ -f "$TEMP_DIR/package-lock.json" ] && [ -f "$APP_DIR/package-lock.json" ]; then
    if ! cmp -s "$TEMP_DIR/package-lock.json" "$APP_DIR/package-lock.json"; then
      log "package-lock.json has changed, triggering full rebuild"
      REBUILD=1
    fi
  fi
fi

# Check if the Dockerfile or docker-compose file has changed
if [ -f "$TEMP_DIR/_deploy/standard.Dockerfile" ] && [ -f "$APP_DIR/_deploy/standard.Dockerfile" ]; then
  if ! cmp -s "$TEMP_DIR/_deploy/standard.Dockerfile" "$APP_DIR/_deploy/standard.Dockerfile"; then
    log "Dockerfile has changed, triggering full rebuild"
    REBUILD=1
  fi
fi

if [ -f "$TEMP_DIR/$DOCKER_COMPOSE_FILE" ] && [ -f "$APP_DIR/$DOCKER_COMPOSE_FILE" ]; then
  if ! cmp -s "$TEMP_DIR/$DOCKER_COMPOSE_FILE" "$APP_DIR/$DOCKER_COMPOSE_FILE"; then
    log "Docker Compose file has changed, triggering full rebuild"
    REBUILD=1
  fi
fi

# Deploy the application
if [ "$REBUILD" -eq 1 ]; then
  log "Performing full rebuild and restart"
  
  # Copy new code to application directory
  rsync -av --exclude 'node_modules' --exclude '.git' --exclude 'public/content/permits' --exclude 'public/content/uploads' "$TEMP_DIR/" "$APP_DIR/"
  
  # Rebuild and restart using Docker Compose
  cd "$APP_DIR"
  docker-compose -f "$DOCKER_COMPOSE_FILE" up -d --build
else
  log "Performing code update without rebuild"
  
  # Copy new code to application directory, preserving special directories
  rsync -av --exclude 'node_modules' --exclude '.git' --exclude 'public/content/permits' --exclude 'public/content/uploads' "$TEMP_DIR/" "$APP_DIR/"
  
  # Find container ID for the Next.js app
  CONTAINER_ID=$(docker ps -qf "name=nextjs-app")
  
  if [ -n "$CONTAINER_ID" ]; then
    log "Restarting Next.js container: $CONTAINER_ID"
    docker restart "$CONTAINER_ID"
  else
    log "Next.js container not found, starting with Docker Compose"
    cd "$APP_DIR"
    docker-compose -f "$DOCKER_COMPOSE_FILE" up -d
  fi
fi

# Restore backed up directories and merge with new content from Git
log "Restoring and merging backed up directories"

# Create permits directory if it doesn't exist
mkdir -p "$APP_DIR/public/content/permits"

# Merge Git permits (if any) with backed up permits
if [ -d "$TEMP_DIR/public/content/permits" ] && [ "$(ls -A "$TEMP_DIR/public/content/permits")" ]; then
  log "Copying permits from Git repository"
  cp -r "$TEMP_DIR/public/content/permits/." "$APP_DIR/public/content/permits/"
fi

# Restore backed up permits (these will take precedence over Git permits)
if [ -d "/tmp/webhook_backup/permits" ] && [ "$(ls -A "/tmp/webhook_backup/permits")" ]; then
  log "Restoring backed up permits"
  cp -r "/tmp/webhook_backup/permits/." "$APP_DIR/public/content/permits/"
fi

# Restore uploads (these should only come from the backup, not Git)
if [ -d "/tmp/webhook_backup/uploads" ] && [ "$(ls -A "/tmp/webhook_backup/uploads")" ]; then
  log "Restoring backed up uploads"
  mkdir -p "$APP_DIR/public/content/uploads"
  cp -r "/tmp/webhook_backup/uploads/." "$APP_DIR/public/content/uploads/"
fi

# Clean up backup
rm -rf "/tmp/webhook_backup"

log "Deployment completed successfully" 