#!/bin/bash
# app_inventory.sh - Identify running applications on app servers
# Claude Sonnet 4.5 - Knowledge Transfer Documentation

HOSTNAME=$(hostname -s)
echo "=========================================="
echo "Application Inventory for: ${HOSTNAME}"
echo "Date: $(date)"
echo "=========================================="
echo

# Function to print section headers
section() {
    echo
    echo "--- $1 ---"
}

# Function to identify Banner module purpose
banner_module_info() {
    local MODULE=$1
    case ${MODULE} in
        *Advise*)
            echo " (Student advising and degree tracking)"
            ;;
        *StudentApi*)
            echo " (Student data REST APIs)"
            ;;
        *BannerAdmin*)
            echo " (Core Banner administration)"
            ;;
        *BannerAccessMgmt*)
            echo " (User access and security management)"
            ;;
        *applicationNavigator*|*ApplicationNavigator*)
            echo " (Banner 9 main navigation interface)"
            ;;
        *BannerExtensibility*)
            echo " (Custom extensions and page customization)"
            ;;
        *EventPublisher*|*BannerEventPublisher*)
            echo " (Event messaging/publishing to external systems)"
            ;;
        *DocumentManagement*)
            echo " (Document storage and retrieval)"
            ;;
        *EllucianMessaging*)
            echo " (Ethos integration messaging adapter)"
            ;;
        *ethosapimanagement*)
            echo " (Ethos API management and monitoring)"
            ;;
        *IntegrationApi*)
            echo " (General integration REST APIs)"
            ;;
        *StudentRegistration*|*registration*)
            echo " (Student self-service registration)"
            ;;
        *wf*|*workflow*)
            echo " (Banner workflow processes)"
            ;;
        dbstatus*)
            echo " (Database health check utility)"
            ;;
        manager|host-manager)
            echo " (Tomcat management interface)"
            ;;
        *)
            echo ""
            ;;
    esac
}

# Check for Tomcat instances
section "TOMCAT INSTANCES"
ps -ef | grep java | grep catalina.base > /tmp/tomcat.$$ 2>/dev/null
if [ -s /tmp/tomcat.$$ ]; then
    grep -o 'catalina.base=[^ ]*' /tmp/tomcat.$$ | cut -d= -f2 | sort -u | while read TOMCAT_BASE; do
        echo "Tomcat Base: ${TOMCAT_BASE}"
        if [ -d "${TOMCAT_BASE}/webapps" ]; then
            echo "  Deployed Apps:"
            ls -1 "${TOMCAT_BASE}/webapps/" 2>/dev/null | while read APP; do
                INFO=$(banner_module_info "${APP}")
                if [ -n "${INFO}" ]; then
                    echo "    ${APP}${INFO}"
                else
                    echo "    ${APP}"
                fi
            done
        fi
        # Check for Banner-specific logging
        BANNER_LOG=$(ps -ef | grep "${TOMCAT_BASE}" | grep -o 'banner.logging.dir=[^ ]*' | cut -d= -f2 | head -1)
        if [ -n "${BANNER_LOG}" ]; then
            echo "  Banner Logging: ${BANNER_LOG}"
        fi
        echo
    done
else
    echo "  None found"
fi
rm -f /tmp/tomcat.$$

# Check for WebLogic
section "WEBLOGIC INSTANCES"
ps -ef | grep java | grep weblogic > /tmp/weblogic.$$ 2>/dev/null
if [ -s /tmp/weblogic.$$ ]; then
    grep -o 'weblogic.Name=[^ ]*' /tmp/weblogic.$$ | cut -d= -f2 | sort -u | while read WL_SERVER; do
        echo "WebLogic Server: ${WL_SERVER}"
        DOMAIN=$(ps -ef | grep "${WL_SERVER}" | grep -o 'weblogic.Domain=[^ ]*' | cut -d= -f2 | head -1)
        if [ -n "${DOMAIN}" ]; then
            echo "  Domain: ${DOMAIN}"
        fi
    done
else
    echo "  None found"
fi
rm -f /tmp/weblogic.$$

# Check for JBoss/WildFly
section "JBOSS/WILDFLY INSTANCES"
ps -ef | grep java | grep jboss > /tmp/jboss.$$ 2>/dev/null
if [ -s /tmp/jboss.$$ ]; then
    grep -o 'jboss.server.base.dir=[^ ]*' /tmp/jboss.$$ | cut -d= -f2 | sort -u | while read JBOSS_BASE; do
        echo "JBoss Base: ${JBOSS_BASE}"
        if [ -d "${JBOSS_BASE}/deployments" ]; then
            echo "  Deployed Apps:"
            ls -1 "${JBOSS_BASE}/deployments/" 2>/dev/null | grep -v '\.deployed$' | sed 's/^/    /'
        fi
    done
else
    echo "  None found"
fi
rm -f /tmp/jboss.$$

# Check for Jenkins
section "JENKINS/CI AGENTS"
ps -ef | grep java | grep jenkins > /dev/null 2>&1
if [ $? -eq 0 ]; then
    ps -ef | grep java | grep jenkins | grep -v grep | awk '{
        for(i=1; i<=NF; i++) {
            if($i ~ /jnlpUrl/) print "  Jenkins Agent: " $(i+1)
        }
    }'
else
    echo "  None found"
fi

# Check for Oracle Enterprise Manager
section "ORACLE ENTERPRISE MANAGER AGENT"
ps -ef | grep emagent | grep -v grep > /dev/null 2>&1
if [ $? -eq 0 ]; then
    AGENT_HOME=$(ps -ef | grep emagent | grep -v grep | awk '{for(i=1;i<=NF;i++) if($i ~ /agent.*agent_inst/) print $i}' | head -1)
    echo "  OEM Agent running"
    if [ -n "${AGENT_HOME}" ]; then
        echo "  Agent Instance: $(dirname ${AGENT_HOME})"
    fi
else
    echo "  None found"
fi

# Check for standalone Java applications
section "OTHER JAVA APPLICATIONS"
ps -ef | grep java | grep -v grep | grep -v catalina | grep -v weblogic | grep -v jboss | grep -v jenkins | grep -v emagent > /tmp/other.$$ 2>/dev/null
if [ -s /tmp/other.$$ ]; then
    awk '{
        # Look for actual -jar invocations, not classpath entries
        for(i=1; i<=NF; i++) {
            if($i == "-jar" && $(i+1) != "") {
                print "  Running JAR: " $(i+1)
            }
        }
    }' /tmp/other.$$ | sort -u | while read LINE; do
        echo "${LINE}"
        if echo "${LINE}" | grep -q workflow; then
            echo "    (Banner workflow engine)"
        fi
    done
    
    # If no -jar found, try to identify main class
    if [ $(awk '{for(i=1;i<=NF;i++) if($i == "-jar") print $i}' /tmp/other.$$ | wc -l) -eq 0 ]; then
        awk '{
            if($NF !~ /^-/ && $NF !~ /java$/ && $NF !~ /grep$/) 
                print "  Main Class: " $NF
        }' /tmp/other.$$ | sort -u
    fi
else
    echo "  None found"
fi
rm -f /tmp/other.$$

# Check listening ports (helps identify what's actually serving)
section "LISTENING PORTS"
if command -v ss > /dev/null 2>&1; then
    ss -tlnp 2>/dev/null | grep java | awk '{print $4}' | sed 's/.*://' | sort -n | uniq -c | awk '{print "  Port " $2 " (" $1 " listener" ($1>1?"s":"") ")"}'
elif command -v netstat > /dev/null 2>&1; then
    netstat -tlnp 2>/dev/null | grep java | awk '{print $4}' | sed 's/.*://' | sort -n | uniq -c | awk '{print "  Port " $2 " (" $1 " listener" ($1>1?"s":"") ")"}'
else
    echo "  (ss/netstat not available)"
fi

# Check listening ports (helps identify what's actually serving)
section "LISTENING PORTS DETAIL"
if command -v ss > /dev/null 2>&1; then
    echo "  Port    Process/Application"
    echo "  ----    -------------------"
    ss -tlnp 2>/dev/null | grep java | awk '{
        # Extract port from local address (format: *:PORT or IP:PORT)
        split($4, addr, ":")
        port = addr[length(addr)]
        
        # Extract process info (inside "users:((" ... "))")
        if (match($0, /users:\(\(.*\)\)/)) {
            proc = substr($0, RSTART, RLENGTH)
            # Try to extract useful info from process
            if (match(proc, /catalina\.base=[^ )]+/)) {
                base = substr(proc, RSTART, RLENGTH)
                gsub(/.*catalina\.base=/, "", base)
                gsub(/\/.*\//, ".../", base)  # Shorten path
                printf "  %-7s Tomcat: %s\n", port, base
            } else if (match(proc, /weblogic\.Name=[^ )]+/)) {
                wl = substr(proc, RSTART, RLENGTH)
                gsub(/.*weblogic\.Name=/, "", wl)
                printf "  %-7s WebLogic: %s\n", port, wl
            } else if (match(proc, /jar [^ ]+/)) {
                jar = substr(proc, RSTART, RLENGTH)
                gsub(/.*\//, "", jar)  # Just filename
                printf "  %-7s JAR: %s\n", port, jar
            } else if (match(proc, /java,[0-9]+/)) {
                pid = substr(proc, RSTART, RLENGTH)
                gsub(/java,/, "", pid)
                printf "  %-7s Java PID: %s\n", port, pid
            } else {
                printf "  %-7s Java (unknown)\n", port
            }
        }
    }' | sort -n -k1
elif command -v netstat > /dev/null 2>&1; then
    echo "  Port    PID/Program"
    echo "  ----    -----------"
    netstat -tlnp 2>/dev/null | grep java | awk '{
        # Extract port
        split($4, addr, ":")
        port = addr[length(addr)]
        
        # PID/Program is in last field for netstat
        printf "  %-7s %s\n", port, $NF
    }' | sort -n -k1
else
    echo "  (ss/netstat not available)"
fi

# Summary
section "SUMMARY"
JAVA_PROCS=$(ps -ef | grep java | grep -v grep | wc -l)
echo "Total Java processes: ${JAVA_PROCS}"

echo
echo "=========================================="
echo "Inventory complete"
echo "=========================================="
