#!/bin/sh
set -e

PROXYCHAINS_CONFIG_FILE="${PROXYCHAINS_CONFIG_FILE:-/etc/proxychains.conf}"
OPENEO_VERIFY_ON_STARTUP="${OPENEO_VERIFY_ON_STARTUP:-1}"

disable_proxy_mode() {
  reason="$1"
  echo "Proxy support disabled: ${reason}" >&2
  ENABLE_PROXYCHAINS=0
  export ENABLE_PROXYCHAINS
  export OPENEO_PROXY_URL=""
  export OPENEO_VERIFY_ON_STARTUP=0
}

proxy_endpoint_reachable() {
  proxy_host="$1"
  proxy_port="$2"
  python - "$proxy_host" "$proxy_port" <<'PY'
import socket
import sys

host = sys.argv[1]
port = int(sys.argv[2])
try:
    with socket.create_connection((host, port), timeout=2):
        sys.exit(0)
except OSError:
    sys.exit(1)
PY
}

setup_proxychains() {
  if [ "${ENABLE_PROXYCHAINS}" != "1" ]; then
    echo "proxychains disabled (ENABLE_PROXYCHAINS=${ENABLE_PROXYCHAINS:-0})"
    return 0
  fi

  if ! command -v proxychains4 >/dev/null 2>&1; then
    disable_proxy_mode "proxychains4 is not installed but ENABLE_PROXYCHAINS=1 was set."
    return 0
  fi

  proxy_type="${PROXYCHAINS_PROXY_TYPE:-socks4}"
  proxy_host="${PROXYCHAINS_PROXY_HOST:-host.docker.internal}"
  proxy_port="${PROXYCHAINS_PROXY_PORT:-10808}"
  chain_mode="${PROXYCHAINS_CHAIN_MODE:-strict_chain}"
  proxy_ip="$(getent hosts "${proxy_host}" | awk 'NR==1 {print $1}')"

  if [ -z "${proxy_ip}" ]; then
    disable_proxy_mode "could not resolve proxy host ${proxy_host}"
    return 0
  fi

  if ! proxy_endpoint_reachable "${proxy_host}" "${proxy_port}"; then
    disable_proxy_mode "proxy ${proxy_host}:${proxy_port} is unreachable"
    return 0
  fi

  cat > "${PROXYCHAINS_CONFIG_FILE}" <<EOF
# Auto-generated by entrypoint.sh
${chain_mode}
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
localnet 127.0.0.0/255.0.0.0
localnet 10.0.0.0/255.0.0.0
localnet 172.16.0.0/255.240.0.0
localnet 192.168.0.0/255.255.0.0
localnet 169.254.0.0/255.255.0.0
[ProxyList]
${proxy_type} ${proxy_ip} ${proxy_port}
EOF

  echo "proxychains enabled via ${proxy_type} ${proxy_host} (${proxy_ip}):${proxy_port}"
}

run_cmd() {
  if [ "${ENABLE_PROXYCHAINS}" = "1" ]; then
    proxychains4 -f "${PROXYCHAINS_CONFIG_FILE}" "$@"
  else
    "$@"
  fi
}

wait_for_db() {
  run_cmd python - <<'PY'
import os
import socket
import sys
import time

host = os.environ.get("DB_HOST", "db")
port = int(os.environ.get("DB_PORT", "3306"))
deadline = time.time() + 90

while time.time() < deadline:
    try:
        with socket.create_connection((host, port), timeout=3):
            print(f"Database is reachable at {host}:{port}")
            sys.exit(0)
    except OSError as exc:
        print(f"Waiting for database {host}:{port}... {exc}")
        time.sleep(2)

print(f"Timed out waiting for database {host}:{port}", file=sys.stderr)
sys.exit(1)
PY
}

setup_proxychains

if [ "${SKIP_MIGRATE}" != "1" ]; then
  wait_for_db
  echo "Running migrations..."
  run_cmd python manage.py repair_location_tables
  run_cmd python manage.py migrate --noinput
  echo "Migrations done."
fi

if [ -n "${DEVELOP}" ] && [ "${SKIP_MIGRATE}" != "1" ]; then
  echo "DEVELOP is set. Seeding demo location_data, weather_data, and farm_data..."
  run_cmd python manage.py seed_location_data
  run_cmd python manage.py seed_weather_data
  run_cmd python manage.py seed_farm_data
  echo "Demo seeders done."
fi

if [ "${OPENEO_VERIFY_ON_STARTUP}" = "1" ]; then
  echo "Checking openEO authentication..."
  if ! run_cmd python manage.py verify_openeo_auth --skip-if-unconfigured; then
    echo "openEO authentication failed; continuing startup with degraded openEO-dependent features." >&2
  fi
else
  echo "Skipping openEO authentication during startup."
fi

echo "Collecting static files..."
run_cmd python manage.py collectstatic --noinput
echo "Static files ready."

echo "Starting command: $*"
if [ "${ENABLE_PROXYCHAINS}" = "1" ]; then
  exec proxychains4 -f "${PROXYCHAINS_CONFIG_FILE}" "$@"
fi
exec "$@"
