#!/usr/bin/env bash
set -euo pipefail

echo "=========================================="
echo "  docker-laravel container starting"
echo "=========================================="
echo "Date:      $(date)"
echo "Hostname:  $(hostname)"
echo "PHP:       $(php -r 'echo PHP_VERSION;')"
echo "Node:      $(node --version 2>/dev/null || echo 'n/a')"
echo "Composer:  $(composer --version --no-ansi 2>/dev/null | head -1 || echo 'n/a')"
echo "=========================================="

start_ts=$(date +%s)

# ---------------------------------------------------------------------------
# 1) Writable directories
# ---------------------------------------------------------------------------
echo "[1/5] Preparing writable dirs..."

mkdir -p /.composer && chmod 0777 /.composer 2>/dev/null || true

if command -v git >/dev/null 2>&1; then
    if git config --system --get-all safe.directory 2>/dev/null | grep -Fxq "/var/www/html"; then
        echo "  git safe.directory already includes /var/www/html"
    else
        git config --system --add safe.directory /var/www/html 2>/dev/null || true
        echo "  Added git safe.directory: /var/www/html"
    fi
fi

# ENABLE_LARAVEL_PERMS defaults to 1 — set to 0 to opt out (e.g. when
# you manage perms yourself with a custom entrypoint or volume init).
# The fix is idempotent and cheap on already-correct trees, so leaving
# it on is the right default.
if [ "${ENABLE_LARAVEL_PERMS:-1}" != "0" ]; then
    echo "  Applying Laravel writable-dir fixes (ENABLE_LARAVEL_PERMS=${ENABLE_LARAVEL_PERMS:-1})"

    APP_ROOT="/var/www/html"

    if [ -d "$APP_ROOT/storage" ] || [ -d "$APP_ROOT/bootstrap/cache" ]; then
        # Pre-create the subdirs that ship empty in fresh Laravel repos
        # plus the ones common Blax packages need (workkit:db:backup writes
        # here). Doing it once at boot — as root — means whichever artisan
        # command runs first never creates them owned by the wrong user.
        mkdir -p \
            "$APP_ROOT/storage/app/public" \
            "$APP_ROOT/storage/app/private" \
            "$APP_ROOT/storage/framework/cache/data" \
            "$APP_ROOT/storage/framework/sessions" \
            "$APP_ROOT/storage/framework/views" \
            "$APP_ROOT/storage/framework/testing" \
            "$APP_ROOT/storage/logs" \
            "$APP_ROOT/storage/backups" \
            "$APP_ROOT/bootstrap/cache" \
            2>/dev/null || true

        # Recursive chown so any stray files written earlier as the wrong
        # user (root, nobody, …) get repaired. chown is fast on already-
        # correct trees — pure stat, no I/O writes.
        chown -R www-data:www-data "$APP_ROOT/storage" "$APP_ROOT/bootstrap/cache" 2>/dev/null || true

        # ug+rwX gives both owner and group write; capital X only adds +x
        # on directories. SGID on the dirs (g+s) makes new files inherit
        # the www-data group — so a file written by a sidecar container
        # running as a different UID still ends up group-writable.
        chmod -R ug+rwX "$APP_ROOT/storage" "$APP_ROOT/bootstrap/cache" 2>/dev/null || true
        find "$APP_ROOT/storage" "$APP_ROOT/bootstrap/cache" -type d -exec chmod g+s {} + 2>/dev/null || true
    else
        echo "  WARN: $APP_ROOT/storage and $APP_ROOT/bootstrap/cache do not exist (volume not mounted yet?)"
    fi
else
    echo "  Skipping Laravel writable-dir fixes (ENABLE_LARAVEL_PERMS=0)"
fi

mkdir -p /var/log/supervisor /var/log/nginx /var/log/php

# ---------------------------------------------------------------------------
# 1b) MySQL/MariaDB client defaults
# ---------------------------------------------------------------------------
# Self-hosted Laravel stacks typically talk to a MySQL container on a
# private docker network. Modern mysql/mariadb server images ship a
# self-signed cert by default, and modern clients auto-enable
# ssl-verify-server-cert when a password is passed on argv (as Laravel's
# `php artisan db` does) — which then fails with
# "TLS/SSL error: self-signed certificate in certificate chain".
#
# Disabling verification here keeps the connection encrypted (the client
# still negotiates TLS) but skips the chain check — the right tradeoff
# for in-cluster traffic where the network is the trust boundary.
# Override per host: set MYSQL_CLIENT_VERIFY=ON, or mount your own
# /etc/mysql/conf.d/*.cnf with stricter settings (later files override
# earlier ones in lexical order).
mkdir -p /etc/mysql/conf.d
cat > /etc/mysql/conf.d/00-laravel-client.cnf <<EOF
[client]
ssl-verify-server-cert=${MYSQL_CLIENT_VERIFY:-OFF}
EOF
chmod 0644 /etc/mysql/conf.d/00-laravel-client.cnf

# ---------------------------------------------------------------------------
# 2) Generate optional supervisor programs based on ENABLE_* env vars
# ---------------------------------------------------------------------------
echo "[2/5] Configuring services..."

echo "  Core programs (conf.d/):"
for f in /etc/supervisor/conf.d/*.conf; do
    [ -f "$f" ] && echo "    $(basename "$f")"
done

LARAVEL_D="/etc/supervisor/laravel.d"
rm -f "${LARAVEL_D}"/*.conf 2>/dev/null || true

if [ "${ENABLE_QUEUE:-false}" = "true" ]; then
    echo "  + queue worker enabled"
    cat > "${LARAVEL_D}/queue.conf" <<'CONF'
[program:queue]
command=/usr/local/bin/php -d variables_order=EGPCS /var/www/html/artisan queue:work --tries=3 --sleep=5 --timeout=600 --max-jobs=500 --max-time=3600
autostart=true
autorestart=true
user=www-data
priority=20
startsecs=5
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0
CONF
fi

if [ "${ENABLE_SCHEDULER:-false}" = "true" ]; then
    echo "  + scheduler enabled"
    cat > "${LARAVEL_D}/scheduler.conf" <<'CONF'
[program:scheduler]
command=/usr/local/bin/php -d variables_order=EGPCS /var/www/html/artisan schedule:work
autostart=true
autorestart=true
user=www-data
priority=20
startsecs=5
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0
CONF
fi

if [ "${ENABLE_HORIZON:-false}" = "true" ]; then
    echo "  + Horizon enabled"
    cat > "${LARAVEL_D}/horizon.conf" <<'CONF'
[program:horizon]
command=/usr/local/bin/php -d variables_order=EGPCS /var/www/html/artisan horizon
autostart=true
autorestart=true
user=www-data
priority=20
startsecs=5
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0
CONF
fi

# Report custom programs
CUSTOM_COUNT=$(find /etc/supervisor/custom.d/ -name '*.conf' 2>/dev/null | wc -l)
if [ "$CUSTOM_COUNT" -gt 0 ]; then
    echo "  Custom programs (custom.d/):"
    for f in /etc/supervisor/custom.d/*.conf; do
        [ -f "$f" ] && echo "    $(basename "$f")"
    done
fi

# ---------------------------------------------------------------------------
# 3) Config tests
# ---------------------------------------------------------------------------
echo "[3/5] Testing configs..."

php-fpm -t 2>&1 || echo "  PHP-FPM config test failed (continuing)"
nginx -t  2>&1 || echo "  Nginx config test failed (continuing)"

# ---------------------------------------------------------------------------
# 4) Diagnostics
# ---------------------------------------------------------------------------
echo "[4/5] Environment"
echo "  APP_ENV=${APP_ENV:-<unset>}"
echo "  APP_DEBUG=${APP_DEBUG:-<unset>}"
echo "  ENABLE_QUEUE=${ENABLE_QUEUE:-false}"
echo "  ENABLE_SCHEDULER=${ENABLE_SCHEDULER:-false}"
echo "  ENABLE_HORIZON=${ENABLE_HORIZON:-false}"
echo "  ENABLE_LARAVEL_PERMS=${ENABLE_LARAVEL_PERMS:-1}"
echo "  MYSQL_CLIENT_VERIFY=${MYSQL_CLIENT_VERIFY:-OFF}"

end_ts=$(date +%s)
echo "  Preflight took $((end_ts - start_ts))s"

# ---------------------------------------------------------------------------
# 5) Launch
# ---------------------------------------------------------------------------
if [ $# -gt 0 ]; then
    echo "[5/5] Running ad-hoc command: $*"
    php-fpm -D
    sleep 1
    nginx
    exec gosu 1000 "$@"
else
    echo "[5/5] Starting Supervisord..."
    echo "=========================================="
    exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
fi
