#!/bin/bash

# S3 File Watcher - Setup & Start Script
# All-in-one script to check prerequisites, configure, and run the S3 File Watcher

set -e

# ═══════════════════════════════════════════════════════════════════════════════
# Configuration
# ═══════════════════════════════════════════════════════════════════════════════

BINARY_NAME="s3-file-watcher"
REQUIRED_ROLE_ARN="arn:aws:iam::103233932089:role/generic-engineer-role"

# Get script directory and set up paths
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BIN_DIR="$SCRIPT_DIR/bin"
BUILD_SCRIPT="$SCRIPT_DIR/build/build.sh"
CONFIG_FILE="$SCRIPT_DIR/config.json"
CONFIG_EXAMPLE="$SCRIPT_DIR/config.example.json"

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

# ═══════════════════════════════════════════════════════════════════════════════
# Helper Functions
# ═══════════════════════════════════════════════════════════════════════════════

print_banner() {
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║   📤  S3 File Watcher - Setup & Start                        ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
}

print_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

print_success() {
    echo -e "${GREEN}  ✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}  ⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}  ❌ $1${NC}"
}

print_info() {
    echo -e "  ℹ️  $1"
}

print_usage() {
    echo "Usage: $0 [OPTIONS] [-- WATCHER_OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --setup-only    Run setup checks only, don't start the watcher"
    echo "  --rebuild       Force rebuild of the binary"
    echo "  --help, -h      Show this help message"
    echo ""
    echo "Watcher Options (passed after --):"
    echo "  --watch-dir     Directory to monitor"
    echo "  --s3-bucket     S3 bucket name"
    echo "  --patterns      File patterns to match"
    echo "  --config        Path to config file"
    echo "  (see README.md for full list)"
    echo ""
    echo "Examples:"
    echo "  $0                                    # Interactive setup and start"
    echo "  $0 --setup-only                       # Check prerequisites only"
    echo "  $0 -- --config config.json            # Start with config file"
    echo "  $0 -- --watch-dir /tmp --s3-bucket mybucket --patterns '*.json'"
    echo ""
}

# ═══════════════════════════════════════════════════════════════════════════════
# Prerequisite Checks
# ═══════════════════════════════════════════════════════════════════════════════

check_awsume() {
    print_step "Checking for awsume..."
    
    # Check if awsume is available (it's typically a shell function/alias)
    if command -v awsume &> /dev/null || type awsume &> /dev/null 2>&1; then
        print_success "awsume is available"
        return 0
    fi
    
    # Check if it's sourced as a function
    if declare -f awsume &> /dev/null; then
        print_success "awsume is available (as function)"
        return 0
    fi
    
    print_error "awsume is not installed or not in PATH"
    echo ""
    echo "  To install awsume:"
    echo "    pip install awsume"
    echo "    awsume-configure"
    echo ""
    echo "  After installation, add to your shell profile:"
    echo "    # For bash (~/.bashrc):"
    echo "    alias awsume='. awsume'"
    echo ""
    echo "    # For zsh (~/.zshrc):"
    echo "    alias awsume='. awsume'"
    echo ""
    echo "  Then restart your shell or run: source ~/.zshrc"
    echo ""
    return 1
}

check_aws_config() {
    print_step "Checking AWS configuration..."
    
    local aws_config="$HOME/.aws/config"
    
    if [ ! -f "$aws_config" ]; then
        print_error "AWS config file not found: $aws_config"
        echo ""
        echo "  Please create ~/.aws/config with your AWS profiles."
        echo "  See README.md for configuration examples."
        echo ""
        return 1
    fi
    
    print_success "AWS config file exists"
    
    # Look for the required role ARN in the config
    print_step "Checking for required role ARN..."
    
    if grep -q "$REQUIRED_ROLE_ARN" "$aws_config"; then
        print_success "Found required role ARN in AWS config"
        
        # Extract the profile name that has this role ARN
        AWS_PROFILE_NAME=$(grep -B10 "$REQUIRED_ROLE_ARN" "$aws_config" | grep -E '^\[profile ' | tail -1 | sed 's/\[profile \(.*\)\]/\1/')
        
        if [ -n "$AWS_PROFILE_NAME" ]; then
            print_success "Associated profile: $AWS_PROFILE_NAME"
            export AWSUME_PROFILE="$AWS_PROFILE_NAME"
            return 0
        else
            print_warning "Could not determine profile name for role ARN"
            return 1
        fi
    else
        print_error "Required role ARN not found in AWS config"
        echo ""
        echo "  The S3 File Watcher requires access to role:"
        echo "    $REQUIRED_ROLE_ARN"
        echo ""
        echo "  Please add a profile to ~/.aws/config like:"
        echo ""
        echo "    [profile your_base_profile]"
        echo "    region = us-east-1"
        echo "    mfa_serial = arn:aws:iam::YOUR_ACCOUNT:mfa/your-username"
        echo ""
        echo "    [profile s3_watcher_profile]"
        echo "    source_profile = your_base_profile"
        echo "    role_session_name = your-username"
        echo "    role_arn = $REQUIRED_ROLE_ARN"
        echo ""
        return 1
    fi
}

check_binary() {
    print_step "Checking for executable..."
    
    local binary_path="$BIN_DIR/$BINARY_NAME"
    
    if [ -f "$binary_path" ] && [ -x "$binary_path" ]; then
        print_success "Executable found: $binary_path"
        export WATCHER_BINARY="$binary_path"
        return 0
    fi
    
    print_warning "Executable not found, will attempt to build"
    return 1
}

check_go() {
    print_step "Checking for Go compiler..."
    
    if command -v go &> /dev/null; then
        local go_version=$(go version | awk '{print $3}')
        print_success "Go is installed: $go_version"
        return 0
    fi
    
    print_error "Go is not installed"
    echo ""
    echo "  To install Go:"
    echo "    macOS:   brew install go"
    echo "    Linux:   sudo apt install golang-go  (or download from golang.org)"
    echo "    Windows: Download from https://golang.org/dl/"
    echo ""
    return 1
}

build_binary() {
    print_step "Building executable..."
    
    if [ ! -f "$BUILD_SCRIPT" ]; then
        print_error "Build script not found: $BUILD_SCRIPT"
        return 1
    fi
    
    chmod +x "$BUILD_SCRIPT"
    
    if "$BUILD_SCRIPT" --current; then
        local binary_path="$BIN_DIR/$BINARY_NAME"
        if [ -f "$binary_path" ]; then
            print_success "Build successful"
            export WATCHER_BINARY="$binary_path"
            return 0
        fi
    fi
    
    print_error "Build failed"
    return 1
}

check_config() {
    print_step "Checking configuration..."
    
    if [ -f "$CONFIG_FILE" ]; then
        print_success "Config file found: $CONFIG_FILE"
        return 0
    fi
    
    if [ -f "$CONFIG_EXAMPLE" ]; then
        print_warning "No config.json found, but config.example.json exists"
        echo ""
        echo "  To create your configuration:"
        echo "    cp config.example.json config.json"
        echo "    # Then edit config.json with your settings"
        echo ""
    else
        print_warning "No configuration file found"
    fi
    
    return 0  # Config is optional if using CLI flags
}

# ═══════════════════════════════════════════════════════════════════════════════
# Authentication
# ═══════════════════════════════════════════════════════════════════════════════

authenticate_aws() {
    print_step "Authenticating with AWS..."
    
    if [ -z "$AWSUME_PROFILE" ]; then
        print_error "No AWS profile detected. Please set up your AWS configuration first."
        return 1
    fi
    
    echo ""
    echo "  Calling: awsume $AWSUME_PROFILE"
    echo ""
    echo "  You may be prompted for your MFA token."
    echo ""
    
    # Note: awsume needs to be sourced, not executed as a subprocess
    # We'll output instructions for the user instead
    print_warning "awsume must be run in your current shell"
    echo ""
    echo "  Please run the following command in your terminal:"
    echo ""
    echo "    awsume $AWSUME_PROFILE"
    echo ""
    echo "  After entering your MFA token, run this script again."
    echo ""
    
    return 1
}

check_aws_credentials() {
    print_step "Checking AWS credentials..."
    
    if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then
        print_success "AWS credentials are set in environment"
        
        if [ -n "$AWS_SESSION_TOKEN" ]; then
            print_success "Session token is present (temporary credentials)"
        fi
        
        # Verify credentials work
        if aws sts get-caller-identity &> /dev/null; then
            local identity=$(aws sts get-caller-identity --output text --query 'Arn' 2>/dev/null)
            print_success "Credentials are valid: $identity"
            return 0
        else
            print_warning "Credentials may be expired or invalid"
            return 1
        fi
    fi
    
    print_warning "No AWS credentials in environment"
    return 1
}

# ═══════════════════════════════════════════════════════════════════════════════
# Main Execution
# ═══════════════════════════════════════════════════════════════════════════════

run_watcher() {
    print_step "Starting S3 File Watcher..."
    echo ""
    
    if [ -z "$WATCHER_BINARY" ]; then
        print_error "No executable path set"
        return 1
    fi
    
    echo "  Command: $WATCHER_BINARY $*"
    echo ""
    echo "════════════════════════════════════════════════════════════════"
    echo ""
    
    exec "$WATCHER_BINARY" "$@"
}

main() {
    print_banner
    
    # Parse arguments
    SETUP_ONLY=false
    FORCE_REBUILD=false
    WATCHER_ARGS=()
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --help|-h)
                print_usage
                exit 0
                ;;
            --setup-only)
                SETUP_ONLY=true
                shift
                ;;
            --rebuild)
                FORCE_REBUILD=true
                shift
                ;;
            --)
                shift
                WATCHER_ARGS=("$@")
                break
                ;;
            *)
                WATCHER_ARGS+=("$1")
                shift
                ;;
        esac
    done
    
    # Track overall status
    ALL_CHECKS_PASSED=true
    
    echo "═══════════════════════════════════════════════════════════════"
    echo "  PREREQUISITE CHECKS"
    echo "═══════════════════════════════════════════════════════════════"
    echo ""
    
    # Check awsume
    if ! check_awsume; then
        ALL_CHECKS_PASSED=false
    fi
    echo ""
    
    # Check AWS config for required role
    if ! check_aws_config; then
        ALL_CHECKS_PASSED=false
    fi
    echo ""
    
    # Check binary (or build if needed)
    if ! check_binary || [ "$FORCE_REBUILD" = true ]; then
        if check_go; then
            echo ""
            if ! build_binary; then
                ALL_CHECKS_PASSED=false
            fi
        else
            ALL_CHECKS_PASSED=false
        fi
    fi
    echo ""
    
    # Check config
    check_config
    echo ""
    
    echo "═══════════════════════════════════════════════════════════════"
    echo "  AUTHENTICATION"
    echo "═══════════════════════════════════════════════════════════════"
    echo ""
    
    # Check/perform authentication - always required
    if ! check_aws_credentials; then
        authenticate_aws
        exit 1  # User needs to run awsume manually
    fi
    echo ""
    
    # Summary
    echo "═══════════════════════════════════════════════════════════════"
    echo "  SUMMARY"
    echo "═══════════════════════════════════════════════════════════════"
    echo ""
    
    if [ "$ALL_CHECKS_PASSED" = true ]; then
        print_success "All prerequisites satisfied!"
        echo ""
        
        if [ "$SETUP_ONLY" = true ]; then
            echo "  Setup complete. You can now run the watcher with:"
            echo ""
            echo "    $0 -- --config config.json"
            echo ""
            echo "  Or with command line options:"
            echo ""
            echo "    $0 -- --watch-dir /path --s3-bucket bucket --patterns '*.json'"
            echo ""
            exit 0
        fi
        
        # Run the watcher
        if [ ${#WATCHER_ARGS[@]} -eq 0 ]; then
            # No args provided, check for config file
            if [ -f "$CONFIG_FILE" ]; then
                run_watcher --config "$CONFIG_FILE"
            else
                print_error "No configuration provided"
                echo ""
                echo "  Please provide either:"
                echo "    - A config.json file"
                echo "    - Command line options (--watch-dir, --s3-bucket, --patterns)"
                echo ""
                echo "  Example:"
                echo "    $0 -- --watch-dir /tmp --s3-bucket mybucket --patterns '*.json'"
                echo ""
                exit 1
            fi
        else
            run_watcher "${WATCHER_ARGS[@]}"
        fi
    else
        print_error "Some prerequisites are not met"
        echo ""
        echo "  Please resolve the issues above and try again."
        echo ""
        exit 1
    fi
}

main "$@"
