#!/bin/bash

# Web Directory Permission Setup Script
# Sets proper ownership and permissions for web directories

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Default web directory - current working directory
DEFAULT_DIR="$(pwd)"

# Function to print colored output
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Function to show usage
show_usage() {
    echo "Usage: $0 [directory_path]"
    echo "       $0 -h|--help"
    echo ""
    echo "Sets proper permissions for web directories:"
    echo "  - Directories: 755 (rwxr-xr-x)"
    echo "  - Files: 644 (rw-r--r--)"
    echo "  - Ownership: www-data:www-data"
    echo "  - Sets group sticky bit on directories"
    echo ""
    echo "Arguments:"
    echo "  directory_path    Path to web directory (default: current directory)"
    echo "  -h, --help        Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0                          # Use current directory and all subdirectories"
    echo "  $0 /var/www/mysite         # Use custom directory"
    echo "  $0 .                       # Explicitly use current directory"
    echo "  $0 ..                      # Use parent directory"
}

# Function to check if user has sudo privileges
check_sudo() {
    if ! sudo -n true 2>/dev/null; then
        print_error "This script requires sudo privileges. Please run with sudo or ensure you have sudo access."
        exit 1
    fi
}

# Function to validate directory
validate_directory() {
    local dir="$1"
    
    # Convert to absolute path
    dir=$(realpath "$dir" 2>/dev/null)
    
    if [[ ! -d "$dir" ]]; then
        print_error "Directory '$dir' does not exist."
        read -p "Do you want to create it? (y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            if sudo mkdir -p "$dir"; then
                print_success "Created directory '$dir'"
            else
                print_error "Failed to create directory '$dir'"
                exit 1
            fi
        else
            print_error "Aborting - directory does not exist."
            exit 1
        fi
    fi
    
    echo "$dir"
}

# Function to check if www-data user/group exists
check_www_data() {
    if ! getent passwd www-data >/dev/null 2>&1; then
        print_error "User 'www-data' does not exist on this system."
        print_warning "This might not be a web server or you might need a different user."
        read -p "Continue anyway? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
    
    if ! getent group www-data >/dev/null 2>&1; then
        print_error "Group 'www-data' does not exist on this system."
        exit 1
    fi
}

# Function to show directory info
show_directory_info() {
    local target_dir="$1"
    
    print_status "Target directory: $target_dir"
    print_status "Absolute path: $(realpath "$target_dir")"
    
    # Count files and directories for progress
    local dir_count=$(find "$target_dir" -type d | wc -l)
    local file_count=$(find "$target_dir" -type f | wc -l)
    local total_items=$((dir_count + file_count))
    
    echo "  - Directories: $dir_count"
    echo "  - Files: $file_count" 
    echo "  - Total items: $total_items"
    
    # Show current permissions of the root directory
    print_status "Current permissions of root directory:"
    ls -ld "$target_dir"
}

# Main function to set permissions
set_permissions() {
    local target_dir="$1"
    
    print_status "Starting permission setup for current directory and all subdirectories..."
    
    # Set ownership recursively
    print_status "Setting ownership to www-data:www-data..."
    if sudo chown -R www-data:www-data "$target_dir"; then
        print_success "Ownership set successfully"
    else
        print_error "Failed to set ownership"
        exit 1
    fi
    
    # Set directory permissions (755) and enable group sticky bit
    print_status "Setting directory permissions to 2755 with group sticky bit..."
    if sudo find "$target_dir" -type d -exec chmod 2755 {} \;; then
        print_success "Directory permissions set successfully"
    else
        print_error "Failed to set directory permissions"
        exit 1
    fi
    
    # Set file permissions (644)
    print_status "Setting file permissions to 644..."
    if sudo find "$target_dir" -type f -exec chmod 644 {} \;; then
        print_success "File permissions set successfully"
    else
        print_error "Failed to set file permissions"
        exit 1
    fi
    
    # Make shell scripts executable if any exist
    local script_count=$(find "$target_dir" -name "*.sh" -type f | wc -l)
    if [[ $script_count -gt 0 ]]; then
        print_status "Found $script_count shell scripts, making them executable..."
        sudo find "$target_dir" -name "*.sh" -type f -exec chmod 755 {} \;
        print_success "Shell scripts made executable"
    fi
    
    # Make other executable files executable (Python scripts, etc.)
    local py_count=$(find "$target_dir" -name "*.py" -type f | wc -l)
    if [[ $py_count -gt 0 ]]; then
        print_status "Found $py_count Python scripts, checking for executable ones..."
        # Only make Python files executable if they have shebang
        sudo find "$target_dir" -name "*.py" -type f -exec sh -c 'head -1 "$1" | grep -q "^#!" && chmod 755 "$1"' _ {} \;
    fi
    
    # Set special permissions for common web files
    if [[ -f "$target_dir/.htaccess" ]]; then
        print_status "Setting .htaccess permissions..."
        sudo chmod 644 "$target_dir/.htaccess"
    fi
    
    # Handle any .git directories (make them less accessible)
    local git_dirs=$(find "$target_dir" -name ".git" -type d | wc -l)
    if [[ $git_dirs -gt 0 ]]; then
        print_status "Found $git_dirs .git directories, setting restricted permissions..."
        sudo find "$target_dir" -name ".git" -type d -exec chmod 750 {} \;
    fi
    
    print_success "All permissions set successfully!"
}

# Function to show summary
show_summary() {
    local target_dir="$1"
    
    echo ""
    print_status "Permission Summary for: $target_dir"
    echo "========================================="
    echo "Ownership: www-data:www-data (all files and directories)"
    echo "Directories: 2755 (rwxr-sr-x) with group sticky bit"
    echo "Files: 644 (rw-r--r--)"
    echo "Shell scripts (*.sh): 755 (rwxr-xr-x)"
    echo "Python scripts with shebang: 755 (rwxr-xr-x)"
    echo ".git directories: 750 (rwxr-x---)"
    echo ""
    
    # Show some example permissions
    print_status "Sample of current permissions:"
    echo "Root directory:"
    sudo ls -ld "$target_dir"
    echo ""
    echo "Contents (first 10 items):"
    sudo ls -la "$target_dir" | head -11
    
    # Show subdirectory count
    local subdir_count=$(find "$target_dir" -mindepth 1 -type d | wc -l)
    if [[ $subdir_count -gt 0 ]]; then
        echo ""
        print_status "Also processed $subdir_count subdirectories recursively"
    fi
}

# Main script execution
main() {
    local target_dir="$DEFAULT_DIR"
    
    # Parse command line arguments
    case "${1:-}" in
        -h|--help)
            show_usage
            exit 0
            ;;
        "")
            target_dir="$DEFAULT_DIR"
            ;;
        *)
            target_dir="$1"
            ;;
    esac
    
    # Validate inputs and prerequisites
    check_sudo
    target_dir=$(validate_directory "$target_dir")
    check_www_data
    
    # Show directory information
    echo ""
    show_directory_info "$target_dir"
    
    # Confirm action
    echo ""
    print_warning "WARNING: This will recursively change ownership and permissions for:"
    print_warning "   Directory: $target_dir"
    print_warning "   ALL subdirectories and files within it"
    print_warning "   Ownership will change to: www-data:www-data"
    print_warning "   Directory permissions: 2755 (with group sticky bit)"
    print_warning "   File permissions: 644"
    echo ""
    
    read -p "Are you sure you want to continue? (y/N): " -n 1 -r
    echo
    
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_status "Operation cancelled by user."
        exit 0
    fi
    
    # Execute permission changes
    set_permissions "$target_dir"
    show_summary "$target_dir"
    
    echo ""
    print_success "Web directory permissions have been set successfully!"
    print_status "You can now copy files to this directory as a member of www-data group."
    print_status "New files will automatically inherit the www-data group due to sticky bit."
}

# Run main function with all arguments
main "$@"