#!/bin/bash
# Prepare /media/thoughtframe/testsite like a server node and write site.sh for it.
# Does not start the container — run upgrade.sh or start.sh after staging.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT_DIR"

SITE_ROOT="${SITE_ROOT:-/media/thoughtframe/testsite}"
NODE="${NODE:-110}"
UID_NOW="$(id -u)"
GID_NOW="$(id -g)"

# Host shape. Leave NETWORK_NAME empty to skip the fixed-IP overlay (e.g. when the
# subnet is already taken on this host) and publish HTTP_PORT instead.
NETWORK_NAME="${NETWORK_NAME-thoughtframe}"
NETWORK_SUBNET="${NETWORK_SUBNET:-172.25.0.0/16}"
HTTP_PORT="${HTTP_PORT-}"
if [ -n "$NETWORK_NAME" ]; then
	IPV4_ADDRESS="${IPV4_ADDRESS:-172.25.0.${NODE}}"
else
	IPV4_ADDRESS=""
fi
if [ -z "$NETWORK_NAME" ] && [ -z "$HTTP_PORT" ]; then
	echo "error: set HTTP_PORT when NETWORK_NAME is empty — the node would be unreachable" >&2
	exit 2
fi

ensure_site_dirs() {
	local root="$1"
	# Pre-create nested bind-mount targets as the deploy user. If Docker creates
	# webapp/WEB-INF/{data,elastic} itself, they become root-owned and bootstrap fails.
	if mkdir -p "${root}/webapp/WEB-INF/data" "${root}/webapp/WEB-INF/elastic" \
		"${root}/data" "${root}/elastic" "${root}/services" "${root}/${NODE}" 2>/dev/null; then
		return 0
	fi
	echo "Host cannot create ${root} — using docker helper as root..."
	docker run --rm \
		-v /media:/media \
		alpine sh -c "mkdir -p '${root}/webapp/WEB-INF/data' '${root}/webapp/WEB-INF/elastic' '${root}/data' '${root}/elastic' '${root}/services' '${root}/${NODE}' && chown -R ${UID_NOW}:${GID_NOW} '${root}'"
}

ensure_site_dirs "$SITE_ROOT"
echo "Site dirs ready under ${SITE_ROOT}"

CONTAINER_NAME="${CONTAINER_NAME:-testsite${NODE}}"
SCRIPTROOT="${SITE_ROOT}/${NODE}"
REGISTRY_DEFAULT="registry.thoughtframe.ai"

# site.sh lives with the node scripts (ThoughtFrame-style) and is also copied to jetty-slim for monorepo helpers.
write_site_sh() {
	local dest="$1"
	cat > "$dest" <<EOF
#!/bin/bash
# Host/process wiring for ${CONTAINER_NAME}

export USERID="${UID_NOW}"
export GROUPID="${GID_NOW}"

export IMAGE="\${IMAGE:-thoughtframe-runtime}"
export TAG="\${TAG:-latest}"
export CONTAINER_NAME="${CONTAINER_NAME}"
export COMPOSE_PROJECT_NAME="${CONTAINER_NAME}"
export HTTP_PORT="${HTTP_PORT}"
export TZ="\${TZ:-America/Halifax}"
export JAVA_OPTS="\${JAVA_OPTS:--Xms512m -Xmx2g}"

export SITE_ROOT="${SITE_ROOT}"
export WEBAPP_HOST="${SITE_ROOT}/webapp"
export DATA_HOST="${SITE_ROOT}/data"
export ELASTIC_HOST="${SITE_ROOT}/elastic"

export NETWORK_NAME="${NETWORK_NAME}"
export NETWORK_SUBNET="${NETWORK_SUBNET}"
export IPV4_ADDRESS="${IPV4_ADDRESS}"

export REGISTRY="\${REGISTRY:-${REGISTRY_DEFAULT}}"
export BOOTSTRAP_WAR_URL="\${BOOTSTRAP_WAR_URL:-}"
EOF
	chmod +x "$dest"
}

write_site_sh "${SCRIPTROOT}/site.sh"
write_site_sh "${ROOT_DIR}/site.sh"
echo "Wrote ${SCRIPTROOT}/site.sh and ${ROOT_DIR}/site.sh"

# Thin node wrappers (same idea as /media/thoughtframe/dam/100/*.sh)
cat > "${SCRIPTROOT}/start.sh" <<EOF
#!/bin/bash
docker start ${CONTAINER_NAME}
EOF

cat > "${SCRIPTROOT}/stop.sh" <<EOF
#!/bin/bash
docker stop -t 60 ${CONTAINER_NAME}
EOF

cat > "${SCRIPTROOT}/restart.sh" <<EOF
#!/bin/bash
docker stop -t 60 ${CONTAINER_NAME} && docker start ${CONTAINER_NAME}
EOF

cat > "${SCRIPTROOT}/logs.sh" <<EOF
#!/bin/bash
docker logs -f --tail 500 ${CONTAINER_NAME}
EOF

cat > "${SCRIPTROOT}/bash.sh" <<EOF
#!/bin/bash
docker exec -it ${CONTAINER_NAME} bash
EOF

# Compose files beside the node scripts so upgrade/create work without the monorepo.
cp -f "${ROOT_DIR}/compose.yml" "${SCRIPTROOT}/compose.yml"
cp -f "${ROOT_DIR}/compose.network.yml" "${SCRIPTROOT}/compose.network.yml"
cp -f "${ROOT_DIR}/compose.ports.yml" "${SCRIPTROOT}/compose.ports.yml"

cat > "${SCRIPTROOT}/create.sh" <<EOF
#!/bin/bash
# First-time (or recreate) container from registry image + local mounts.
set -euo pipefail
cd "\$(dirname "\$0")"
# shellcheck disable=SC1091
source ./site.sh

if [ -n "\${NETWORK_NAME:-}" ]; then
	docker network inspect "\${NETWORK_NAME}" >/dev/null 2>&1 || \\
		docker network create --subnet "\${NETWORK_SUBNET:-172.25.0.0/16}" "\${NETWORK_NAME}"
fi

FULL_IMAGE="\${REGISTRY}/\${IMAGE}:\${TAG}"
echo "Pulling \${FULL_IMAGE} ..."
docker pull "\${FULL_IMAGE}" || docker pull "\${IMAGE}:\${TAG}"
docker tag "\${FULL_IMAGE}" "\${IMAGE}:\${TAG}" 2>/dev/null || true

COMPOSE=(docker compose -f compose.yml)
if [ -n "\${NETWORK_NAME:-}" ]; then
	COMPOSE+=(-f compose.network.yml)
fi
if [ -n "\${HTTP_PORT:-}" ]; then
	COMPOSE+=(-f compose.ports.yml)
fi

docker rm -f "\${CONTAINER_NAME}" 2>/dev/null || true
"\${COMPOSE[@]}" -p "\${COMPOSE_PROJECT_NAME}" up -d
echo "Created \${CONTAINER_NAME}"
if [ -n "\${IPV4_ADDRESS:-}" ]; then
	echo "     http://\${IPV4_ADDRESS}:8080/ on network \${NETWORK_NAME}"
fi
if [ -n "\${HTTP_PORT:-}" ]; then
	echo "     http://<host>:\${HTTP_PORT}/"
fi
EOF

cat > "${SCRIPTROOT}/upgrade.sh" <<EOF
#!/bin/bash
# Pull a new baked image and recreate the container. Entrypoint overlays lib/base/web.xml/startup.xconf;
# data/elastic/site files on the mounts are kept.
set -euo pipefail
cd "\$(dirname "\$0")"
# shellcheck disable=SC1091
source ./site.sh

FULL_IMAGE="\${REGISTRY}/\${IMAGE}:\${TAG}"
echo "Pulling \${FULL_IMAGE} ..."
docker pull "\${FULL_IMAGE}" || docker pull "\${IMAGE}:\${TAG}"
docker tag "\${FULL_IMAGE}" "\${IMAGE}:\${TAG}" 2>/dev/null || true

COMPOSE=(docker compose -f compose.yml)
if [ -n "\${NETWORK_NAME:-}" ]; then
	COMPOSE+=(-f compose.network.yml)
fi
if [ -n "\${HTTP_PORT:-}" ]; then
	COMPOSE+=(-f compose.ports.yml)
fi

./stop.sh || true
docker rm -f "\${CONTAINER_NAME}" 2>/dev/null || true
"\${COMPOSE[@]}" -p "\${COMPOSE_PROJECT_NAME}" up -d
echo "Upgrade complete (\${IMAGE}:\${TAG})."

# Each pull leaves the previous image untagged; on a root-disk site they fill the disk and push the
# embedded OpenSearch past its flood-stage watermark (every index goes read-only).
docker image prune -f || echo "WARNING: docker image prune failed; check free disk before the next upgrade" >&2
EOF

chmod +x "${SCRIPTROOT}"/{start,stop,restart,logs,bash,create,upgrade}.sh

echo "Node scripts in ${SCRIPTROOT}:"
ls -1 "${SCRIPTROOT}"/*.sh
echo
echo "Next (fresh box):"
echo "  cd ${SCRIPTROOT} && ./create.sh"
echo "Then day-to-day: ./start.sh ./stop.sh ./logs.sh ./upgrade.sh"
if [ -n "${IPV4_ADDRESS}" ]; then
	echo "URL: http://${IPV4_ADDRESS}:8080/"
fi
if [ -n "${HTTP_PORT}" ]; then
	echo "URL: http://$(hostname):${HTTP_PORT}/"
fi
