#!/bin/bash
# SSH Tunnel Docker Container Script
# Maintains SSH tunnel to Oracle database

set -e

# Configuration from environment variables
SSH_SERVER="${SSH_SERVER:-83.103.197.79}"
SSH_PORT="${SSH_PORT:-22122}"
SSH_USER="${SSH_USER:-roa2web}"
SSH_KEY_PATH="${SSH_KEY_PATH:-/home/tunnel/.ssh/roa_oracle_server}"
LOCAL_PORT="${LOCAL_PORT:-1521}"
REMOTE_HOST="${REMOTE_HOST:-10.0.20.36}"
REMOTE_PORT="${REMOTE_PORT:-1521}"

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

log() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

log "${BLUE}🚀 Starting SSH tunnel container...${NC}"
log "${BLUE}Tunnel: localhost:${LOCAL_PORT} -> ${SSH_SERVER}:${SSH_PORT} -> ${REMOTE_HOST}:${REMOTE_PORT}${NC}"

# Check if SSH key exists
if [ ! -f "$SSH_KEY_PATH" ]; then
    log "${RED}❌ SSH private key not found at $SSH_KEY_PATH${NC}"
    log "${YELLOW}Please mount your SSH key as a volume:${NC}"
    log "${YELLOW}  -v ~/.ssh/roa_oracle_server:/home/tunnel/.ssh/roa_oracle_server:ro${NC}"
    exit 1
fi

# Set proper permissions for SSH key (skip if operation not permitted)
chmod 600 "$SSH_KEY_PATH" 2>/dev/null || log "${YELLOW}⚠️  Could not set SSH key permissions (continuing anyway)${NC}"

# Create SSH config for better connection handling
mkdir -p /home/tunnel/.ssh
cat > /home/tunnel/.ssh/config << EOF
Host tunnel-server
    HostName ${SSH_SERVER}
    Port ${SSH_PORT}
    User ${SSH_USER}
    IdentityFile ${SSH_KEY_PATH}
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    ServerAliveInterval 30
    ServerAliveCountMax 3
    TCPKeepAlive yes
    ExitOnForwardFailure yes
    BatchMode yes
EOF

chmod 600 /home/tunnel/.ssh/config

# Function to establish tunnel
establish_tunnel() {
    log "${YELLOW}🔗 Establishing SSH tunnel...${NC}"
    
    ssh -N -T \
        -o ConnectTimeout=30 \
        -o ServerAliveInterval=30 \
        -o ServerAliveCountMax=3 \
        -o ExitOnForwardFailure=yes \
        -o GatewayPorts=yes \
        -L "0.0.0.0:${LOCAL_PORT}:${REMOTE_HOST}:${REMOTE_PORT}" \
        tunnel-server &
    
    SSH_PID=$!
    echo $SSH_PID > /tmp/ssh_tunnel.pid
    
    # Wait a moment for tunnel to establish
    sleep 5
    
    # Test tunnel
    if nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then
        log "${GREEN}✅ SSH tunnel established successfully (PID: $SSH_PID)${NC}"
        return 0
    else
        log "${RED}❌ Failed to establish SSH tunnel${NC}"
        return 1
    fi
}

# Function to monitor tunnel
monitor_tunnel() {
    while true; do
        if [ -f /tmp/ssh_tunnel.pid ]; then
            local pid=$(cat /tmp/ssh_tunnel.pid)
            
            # Check if process is still running
            if ! ps -p "$pid" > /dev/null 2>&1; then
                log "${YELLOW}⚠️ SSH tunnel process died, restarting...${NC}"
                establish_tunnel
            fi
            
            # Check if port is still accessible
            if ! nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then
                log "${YELLOW}⚠️ SSH tunnel port not accessible, restarting...${NC}"
                if [ -f /tmp/ssh_tunnel.pid ]; then
                    kill $(cat /tmp/ssh_tunnel.pid) 2>/dev/null || true
                    rm -f /tmp/ssh_tunnel.pid
                fi
                establish_tunnel
            fi
        else
            log "${YELLOW}⚠️ SSH tunnel not running, starting...${NC}"
            establish_tunnel
        fi
        
        sleep 30
    done
}

# Function to handle shutdown gracefully
cleanup() {
    log "${YELLOW}📋 Shutting down SSH tunnel...${NC}"
    if [ -f /tmp/ssh_tunnel.pid ]; then
        local pid=$(cat /tmp/ssh_tunnel.pid)
        kill "$pid" 2>/dev/null || true
        rm -f /tmp/ssh_tunnel.pid
    fi
    log "${GREEN}✅ SSH tunnel stopped${NC}"
    exit 0
}

# Set up signal handlers
trap cleanup SIGTERM SIGINT

# Initial tunnel establishment
if establish_tunnel; then
    log "${GREEN}🎉 SSH tunnel container ready!${NC}"
    log "${BLUE}Oracle database accessible at localhost:${LOCAL_PORT}${NC}"
    
    # Start monitoring
    monitor_tunnel
else
    log "${RED}💥 Failed to establish initial SSH tunnel${NC}"
    exit 1
fi