#!/usr/bin/env sh
#
# bootstrap — turn this template into a concrete website.
#
# The template ships as a fully buildable reference site whose identity is the
# neutral placeholder "Site" / "site". This script rewrites those placeholders,
# in place, to the values you provide — then removes itself.
#
# Run once, from the repository root:
#
#   ./Scripts/bootstrap        # or: make bootstrap
#
# It is idempotent only in the sense that it self-destructs: once run, the
# placeholders are gone and the script (and its scaffolding) are deleted.

set -eu

# --- Preconditions ------------------------------------------------------------

if [ ! -d "Services/Website" ]; then
	echo "error: run this from the repository root (Services/Website not found)." >&2
	exit 1
fi

XCODEPROJ="./Site.xcodeproj"

# The placeholder origin the crawler files ship with. It is an RFC 2606 reserved
# domain, so an un-bootstrapped copy can never point a crawler at a real site.
PLACEHOLDER_URL="https://site.example.com"
PLACEHOLDER_URL_PATTERN='https://site\.example\.com'

# --- Prompts ------------------------------------------------------------------

printf 'Site display name (PascalCase, e.g. Berlin) [Site]: '
read -r NAME
NAME="${NAME:-Site}"

DEFAULT_SLUG="$(printf '%s' "$NAME" | tr '[:upper:]' '[:lower:]')"
printf 'Project slug (lowercase, used for owner/db/compose, e.g. loud-berlin) [%s]: ' "$DEFAULT_SLUG"
read -r SLUG
SLUG="${SLUG:-$DEFAULT_SLUG}"

printf 'Canonical site URL (scheme + host, e.g. https://berlin.example.com) [%s]: ' "$PLACEHOLDER_URL"
read -r URL
URL="${URL:-$PLACEHOLDER_URL}"
URL="${URL%/}" # the rewrites append their own path, so drop a trailing slash

# The URL is interpolated into a sed replacement (with `|` as the delimiter) and
# into the crawler files, so reject anything that is not a plain scheme + host.
case "$URL" in
	http://* | https://*) ;;
	*)
		echo "error: the canonical site URL must start with http:// or https:// (got \"$URL\")." >&2
		exit 1
		;;
esac
case "$URL" in
	*[!-A-Za-z0-9:/._~]*)
		echo "error: the canonical site URL contains unexpected characters (got \"$URL\")." >&2
		exit 1
		;;
esac

echo
echo "  display name : $NAME       (server name \"${NAME}Website\", ${NAME}.xcodeproj)"
echo "  slug         : $SLUG       (container owner, database name/user, compose project)"
echo "  canonical URL: $URL       (robots.txt sitemap reference, sitemap.xml entry)"
echo
printf 'Apply these values? [y/N]: '
read -r CONFIRM
case "$CONFIRM" in
	y | Y | yes | YES) ;;
	*)
		echo "Aborted. Nothing was changed."
		exit 1
		;;
esac

# --- Helpers ------------------------------------------------------------------

# Portable in-place sed (works on both BSD/macOS and GNU/Linux).
rewrite() {
	file="$1"
	shift
	[ -f "$file" ] || return 0
	tmp="${file}.bootstrap.tmp"
	sed "$@" "$file" >"$tmp" && mv "$tmp" "$file"
}

W="Services/Website"

# --- Rewrites -----------------------------------------------------------------

# Swift constants: server name + database name/username.
rewrite "$W/Sources/Library/Public/Extensions/String+Constants.swift" \
	-e "s/SiteWebsite/${NAME}Website/g" \
	-e "s/= \"site\"/= \"${SLUG}\"/g"

# Local env example.
rewrite "$W/.env.local" \
	-e "s/SiteWebsite/${NAME}Website/g" \
	-e "s/^HOST_OWNER=site\$/HOST_OWNER=${SLUG}/" \
	-e "s/^DATABASE_NAME=site\$/DATABASE_NAME=${SLUG}/" \
	-e "s/^DATABASE_USERNAME=site\$/DATABASE_USERNAME=${SLUG}/" \
	-e "s/^DATABASE_PASSWORD=site\$/DATABASE_PASSWORD=${SLUG}/"

# Production compose.
rewrite "$W/docker-compose.yml" \
	-e "s/SiteWebsite/${NAME}Website/g" \
	-e "s/^name: site-platform\$/name: ${SLUG}-platform/" \
	-e "s/DATABASE_NAME:-site}/DATABASE_NAME:-${SLUG}}/" \
	-e "s/DATABASE_USERNAME:-site}/DATABASE_USERNAME:-${SLUG}}/"

# Local override compose.
rewrite "$W/docker-compose.override.yml" \
	-e "s/HOST_OWNER:-site}/HOST_OWNER:-${SLUG}}/" \
	-e "s/DATABASE_NAME:-site}/DATABASE_NAME:-${SLUG}}/" \
	-e "s/DATABASE_USERNAME:-site}/DATABASE_USERNAME:-${SLUG}}/" \
	-e "s/DATABASE_PASSWORD:-site}/DATABASE_PASSWORD:-${SLUG}}/"

# Makefile db-shell fallbacks.
rewrite "$W/Makefile" \
	-e "s/),site)/),${SLUG})/g"

# Crawler files: the absolute origin they must carry. `|` is the sed delimiter,
# since both the placeholder and the replacement contain slashes.
rewrite "$W/Resources/Static/robots.txt" \
	-e "s|${PLACEHOLDER_URL_PATTERN}|${URL}|g"

rewrite "$W/Resources/Static/sitemap.xml" \
	-e "s|${PLACEHOLDER_URL_PATTERN}|${URL}|g"

# Service README.
rewrite "$W/README.md" \
	-e "s/^# Site Website\$/# ${NAME} Website/" \
	-e "s/\*\*Site\*\*/**${NAME}**/" \
	-e "s/SiteWebsite/${NAME}Website/g" \
	-e "s/\`site\`/\`${SLUG}\`/g"

# Xcode project: PBXProject name + directory.
if [ -d "$XCODEPROJ" ]; then
	rewrite "$XCODEPROJ/project.pbxproj" -e "s/\"Site\"/\"${NAME}\"/g"

	# Skip the rename when the display name was left as the placeholder: the
	# source and destination are then the same path, and `mv dir dir` fails
	# (it moves the directory into itself), which would abort the run here —
	# after the rewrites, but before the self-cleanup.
	XCODEPROJ_RENAMED="./${NAME}.xcodeproj"

	if [ "$XCODEPROJ" != "$XCODEPROJ_RENAMED" ]; then
		if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
			git mv "$XCODEPROJ" "$XCODEPROJ_RENAMED" 2>/dev/null || mv "$XCODEPROJ" "$XCODEPROJ_RENAMED"
		else
			mv "$XCODEPROJ" "$XCODEPROJ_RENAMED"
		fi
	fi
fi

# --- Optional: fresh git history ---------------------------------------------

echo
printf 'Start a fresh git history (drops the template history)? [y/N]: '
read -r FRESH
case "$FRESH" in
	y | Y | yes | YES)
		if command -v git >/dev/null 2>&1; then
			rm -rf .git
			git init -q
			echo "Reinitialised git. Remember to add your remote and commit."
		fi
		;;
	*) ;;
esac

# --- Self-cleanup -------------------------------------------------------------

rm -f Scripts/bootstrap
rmdir Scripts 2>/dev/null || true
rm -f Makefile          # root convenience Makefile (bootstrap only)
rm -f README.md       # template usage docs
rm -rf .gitea           # Gitea template metadata

# --- Done ---------------------------------------------------------------------

cat <<EOF

Done. "${NAME}" (slug "${SLUG}") is ready.

Next steps:
  1. Replace the placeholder content:
       - $W/Sources/Library/Catalogs/Localizable.xcstrings   (copy)
       - $W/Sources/Library                                   (landing / 404 pages)
       - $W/Resources/Static                                  (css, js, favicon, icons)
       - $W/Resources/Static/site.webmanifest                 (name / short_name)
  2. Set a real database password in a git-ignored $W/.env
     (the committed .env.local defaults the password to the slug — do NOT ship that).
  3. Analytics ships OFF, and stays off until you opt in. To enable it: point
     String.Analytics.origin at your own Umami instance (it defaults to the
     reserved https://analytics.example.com), allow that origin in
     security.contentSecurityPolicy, then set ANALYTICS_WEBSITE_ID.
  4. Point the git remote at your new repository:
       git remote set-url origin <new-repo-url>     # or 'git remote add origin ...'
  5. Build and run:
       cd $W && make site-run

The Persistence package still ships an ExampleRecord / ExampleRepository sample
model — replace it with your real domain models when you add persistence.
EOF

if [ "$URL" = "$PLACEHOLDER_URL" ]; then
	cat <<EOF

WARNING: the canonical site URL was left as the placeholder "${PLACEHOLDER_URL}".
Set the real origin in $W/Resources/Static/robots.txt and sitemap.xml before
going live, or crawlers will be pointed at a reserved example domain.
EOF
fi
