#!/usr/bin/env bash
#
# Generate the reverse proxy's Caddyfile from CoreSystemConfig.json.
#
# Called by the container-host ISO builder and by setup-container-host.sh, so the proxy
# is configured from the same single source as everything else — the hostname it serves,
# the ports it forwards to, and which services exist at all.
#
#   tools/generate-caddyfile.sh <destination-path>
#
# See proxy/README.md for why this exists (short version: the admin panel's token is in
# a URL, the registration camera needs a secure context, and a mixed-content page can't
# call its own API).

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/coreconfig.sh
source "${SCRIPT_DIR}/lib/coreconfig.sh"

DEST="${1:-}"
[[ -n "$DEST" ]] || core_die "Usage: $0 <destination Caddyfile path>"

core_load

if [[ "$CORE_PROXY_ENABLED" != "true" ]]; then
  core_warn "proxy.enabled is false — nothing to generate."
  exit 0
fi

# TLS directive. `tls internal` is Caddy's own CA; the custom branch points at mounted
# files. Note the paths are the CONTAINER's, not the host's — the compose service
# mounts them read-only at these locations.
if [[ "$CORE_PROXY_TLS" == "custom" ]]; then
  TLS_LINE="    tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem"
else
  TLS_LINE="    tls internal"
fi

# Only proxy services that exist. A route to a container that was never started would
# give a 502 that looks like a proxy fault rather than a service that isn't enabled.
PANTRY_ROUTE=""
if [[ "$CORE_ENABLE_PANTRY_VISION" == "true" ]]; then
  PANTRY_ROUTE="
    # pantry-vision's API, same prefix-stripping as identity's.
    handle_path /api/pantry/* {
        reverse_proxy pantry-vision:${CORE_PORT_PANTRY_VISION}
    }
"
fi

mkdir -p "$(dirname "$DEST")"
cat > "$DEST" <<EOF
# GENERATED from CoreSystemConfig.json by tools/generate-caddyfile.sh.
# Edit the config and re-run; edits here are overwritten on the next build.
#
# One HTTPS front door for this repo's own services. Home Assistant, Grocy, Frigate,
# Portainer and the rest keep their own ports and are deliberately NOT behind this —
# fronting HA in particular brings its own auth and websocket concerns, and none of the
# problems this proxy solves (see proxy/README.md) need it.

{
    # No ACME account e-mail: with 'tls internal' there is no public CA involved, and
    # with 'custom' the certificate is already issued. Neither path talks to Let's
    # Encrypt, which is what keeps this working on a network with no WAN access at all.
    admin off
}

# --- HTTP: redirect everything, permanently -----------------------------------------
# Caddy does this automatically for a site with TLS, but it is written out explicitly
# because "the tool probably handles it" is a poor thing to rely on for the one rule
# that stops a token being sent in cleartext.
http://${CORE_PROXY_HOSTNAME} {
    redir https://{host}{uri} permanent
}

# --- HTTPS ---------------------------------------------------------------------------
https://${CORE_PROXY_HOSTNAME} {
${TLS_LINE}

    # identity's API. handle_path strips the matched prefix, so /api/identity/people
    # reaches the container as /people — the service is unchanged and unaware it is
    # behind a proxy.
    handle_path /api/identity/* {
        reverse_proxy identity:${CORE_PORT_IDENTITY}
    }
${PANTRY_ROUTE}
    # Everything else is the static frontend: dashboard.html, register.html, admin.html.
    handle {
        reverse_proxy identity-web:80
    }

    # The admin panel's token is in its URL, so keep that URL out of shared caches and
    # out of anything that might log a referer to a third party.
    header {
        Referrer-Policy "no-referrer"
        Cache-Control "no-store"
        X-Content-Type-Options "nosniff"
        # HSTS is deliberately NOT set. With 'tls internal' it would pin browsers to
        # HTTPS for a hostname whose CA they may not trust yet, turning a dismissible
        # warning into a hard failure that is genuinely awkward to undo.
    }

    log {
        output stderr
        format console
    }
}
EOF

core_log "Wrote ${DEST}"
echo "  Front door : https://${CORE_PROXY_HOSTNAME}"
echo "  Admin panel: ${CORE_ADMIN_URL}"
if [[ "$CORE_PROXY_TLS" == "internal" ]]; then
  echo
  echo "  TLS is Caddy's internal CA. Browsers will warn until you install its root:"
  echo "      tools/export-proxy-ca.sh"
fi
