#!/usr/xpg4/bin/sh

# Solaris Infrastructure Agent Patch Script (POSIX sh compatible)

. "$1"
export BACKUP_DIR=/tmp
export LOG_FILE=/var/log/whatap_update.log
export PATCH_RESULT_FILE="$INSTALL_DIR/patch_history.log"
CONF_FILE="$INSTALL_DIR/conf/whatap.conf"
CONF_BACKUP="$BACKUP_DIR/whatap.conf"

if [ -z "${pkg:-}" ]; then
	echo "usage: $0 <config-file>"
	exit 2
fi

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

error_exit() {
	log "ERROR: $1"
	exit 1
}

error() {
	log "ERROR: $1"
}

write_patch_result() {
	status="$1"
	patch_version="$2"
	start_time="$3"
	error_message="$4"
	end_time=$(date '+%Y-%m-%d %H:%M:%S')

	echo "$status|$patch_version|$start_time|$end_time|$error_message" >> "$PATCH_RESULT_FILE"
	log "Patch result written to $PATCH_RESULT_FILE"
}

get_patch_version() {
	pkg_file="$1"
	version=""

	# Try extracting to temp dir and running the binary
	tmpdir="/tmp/whatap_ver.$$"
	rm -rf "$tmpdir" 2>/dev/null
	mkdir -p "$tmpdir" 2>/dev/null
	if [ -d "$tmpdir" ]; then
		gunzip -c "$pkg_file" 2>/dev/null | tar xf - -C "$tmpdir" 2>/dev/null
		if [ -x "$tmpdir/whatap-infra/whatap_infrad" ]; then
			version=$("$tmpdir/whatap-infra/whatap_infrad" version 2>/dev/null | head -1)
		fi
		rm -rf "$tmpdir"
	fi

	# Fallback: extract from filename
	if [ -z "$version" ]; then
		version=$(basename "$pkg_file" | sed 's/.*-\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/')
		if [ "$version" = "$(basename "$pkg_file")" ]; then
			version=$(basename "$pkg_file" | sed 's/.*-\([0-9][0-9]*\.[0-9][0-9]*\)-\([0-9][0-9]*\).*/\1.\2/')
			if [ "$version" = "$(basename "$pkg_file")" ]; then
				version="unknown"
			fi
		fi
	fi

	echo "$version"
}

backup_config() {
	log "backing up config..."
	if [ -f "$CONF_FILE" ]; then
		cp -p "$CONF_FILE" "$CONF_BACKUP" || error_exit "failed to backup config"
		log "config backed up to $CONF_BACKUP"
	else
		log "no config file found to backup"
	fi
}

restore_config() {
	log "restoring config..."
	if [ -f "$CONF_BACKUP" ]; then
		cp -p "$CONF_BACKUP" "$CONF_FILE" || error "failed to restore config"
		log "config restored from $CONF_BACKUP"
	else
		log "no config backup found to restore"
	fi
}

stop_service() {
	log "service stop..."

	PID_FILE="$INSTALL_DIR/conf/whatap.pid"
	SAVED_PID=""
	if [ -f "$PID_FILE" ]; then
		SAVED_PID=$(cat "$PID_FILE" 2>/dev/null | tr -d ' \t\r\n')
		log "pre-stop pid from $PID_FILE: $SAVED_PID"
	else
		log "$PID_FILE not found"
	fi

	/etc/init.d/whatap-infra stop
	if [ $? -ne 0 ]; then
		log "service stop error"
	fi
	sleep 3

	if [ -n "$SAVED_PID" ]; then
		if ps -p "$SAVED_PID" 2> /dev/null | grep "whatap_" > /dev/null 2>&1; then
			log "pid $SAVED_PID still alive, sending SIGKILL"
			kill -9 "$SAVED_PID" 2>/dev/null
			sleep 3 
			if ps -p "$SAVED_PID" 2> /dev/null | grep "whatap_" > /dev/null 2>&1; then
				error_exit "pid $SAVED_PID still alive, error"
			fi
		fi
	fi

	log "service stop ok"
}

start_service() {
	log "service start..."
	rm -f "$INSTALL_DIR/conf/whatap_infrad.pid"
	/etc/init.d/whatap-infra start
	if [ $? -ne 0 ]; then
		log "service start error"
	fi
	log "service start ok"
}

backup_whatap() {
	log "creating backup of existing installation..."
	if [ -d "$INSTALL_DIR" ]; then
		mkdir -p "$BACKUP_DIR"
		# cp -Rp cannot copy socket files (e.g. whatap_infrad.sock) - ignore those errors
		cp -Rp "$INSTALL_DIR" "$BACKUP_DIR/" 2>/dev/null || true
		if [ ! -d "$BACKUP_DIR/infra" ]; then
			error_exit "failed to create backup"
		fi
		# Clean up any socket files that may have been partially copied
		find "$BACKUP_DIR/infra" -type s -exec rm -f {} \; 2>/dev/null
		log "backup created at $BACKUP_DIR"
	else
		log "no existing installation found to backup"
	fi
	log "backup ok"
}

rollback_whatap() {
	log "rollback start..."
	stop_service
	if [ -n "$INSTALL_DIR" ] && [ "$INSTALL_DIR" != "/" ]; then
		rm -rf "$INSTALL_DIR" 2>/dev/null
	fi
	mkdir -p "$INSTALL_DIR"
	(cd "$BACKUP_DIR/infra" && cp -Rp . "$INSTALL_DIR/") || error_exit "failed to rollback"
	start_service
	log "rollback ok"
}

install_package() {
	log "install $pkg ..."

	cd /tmp
	gunzip -c "$pkg" | tar xvf -
	if [ $? -ne 0 ]; then
		error "$pkg extract fail"
		return 1
	fi

	if [ -x "./whatap-infra/install.sh" ]; then
		awk 'BEGIN{for(i=0;i<20;i++)print "n"}' | ./whatap-infra/install.sh
		rc=$?
		if [ $rc -ne 0 ]; then
			error "$pkg install fail"
			rm -rf "whatap-infra"
			return 1
		fi
	else
		error "install.sh not found in package"
		rm -rf "whatap-infra"
		return 1
	fi

	rm -rf "whatap-infra"
	log "$pkg install ok"
	return 0
}

test_agent() {
	log "testing agent..."

	if [ -x "$INSTALL_DIR/whatap_infrad" ]; then
		version_output=$("$INSTALL_DIR/whatap_infrad" version 2>&1)
		if [ $? -ne 0 ]; then
			error "Agent Version Check Failed"
			return 1
		fi
		echo "$version_output"
		PATCH_VERSION=$(echo "$version_output" | head -1 | awk '{print $NF}')
		export PATCH_VERSION
		export WHATAP_HOME="$INSTALL_DIR/conf"
		"$INSTALL_DIR/whatap_infrad" boot-test
		if [ $? -ne 0 ]; then
			error "Agent Test Check Failed"
			return 1
		fi
		return 0
	else
		error "agent test fail"
		return 1
	fi
}

check_root() {
	log "checking root privileges..."
	if [ "$(id | sed 's/uid=\([0-9]*\).*/\1/')" -ne 0 ]; then
		error_exit "This script must be run as root"
	fi
	log "check root ok"
}

# --- Main ---
check_root

PATCH_START_TIME=$(date '+%Y-%m-%d %H:%M:%S')
PATCH_VERSION=''
log "Starting patch process : $PATCH_START_TIME"

stop_service
backup_whatap
backup_config

install_package

if [ $? -ne 0 ]; then
	log "Package installation failed - rollback"
	rollback_whatap
	write_patch_result "rollback" "$PATCH_VERSION" "$PATCH_START_TIME" "Package installation failed"
else
	log "install complete"
	restore_config
	test_agent
	if [ $? -ne 0 ]; then
		log "Agent test failed - rollback"
		rollback_whatap
		write_patch_result "rollback" "$PATCH_VERSION" "$PATCH_START_TIME" "Agent test failed"
	else
		start_service
		log "Patch completed successfully"
		write_patch_result "success" "$PATCH_VERSION" "$PATCH_START_TIME" ""
	fi
fi
