#!/usr/bin/env bash
#
# deploy.sh - one-shot deployment of the Meeting Management System onto a VPS.
#
# Installs the web stack, configures Apache, obtains an HTTPS certificate,
# installs and configures a coturn TURN relay (required for video calls between
# people on different networks), generates fresh secrets, and sets permissions.
#
# USAGE (as root, on the VPS, from inside the extracted project folder):
#     sudo bash deploy.sh
#
# It will prompt for your domain and an email address for the SSL certificate.
#
set -euo pipefail

APP_DIR="/var/www/mms"
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

info()  { echo -e "\n\033[1;36m==> $*\033[0m"; }
warn()  { echo -e "\033[1;33m[!] $*\033[0m"; }
die()   { echo -e "\033[1;31m[x] $*\033[0m" >&2; exit 1; }

# ---------------------------------------------------------------
# Preflight
# ---------------------------------------------------------------
[ "$(id -u)" -eq 0 ] || die "Please run with sudo: sudo bash deploy.sh"

[ -f "$SRC_DIR/public/index.php" ] || \
  die "Run this from inside the extracted project folder (public/index.php not found here)."

if   command -v apt-get >/dev/null 2>&1; then PKG=apt;  APACHE=apache2
elif command -v dnf     >/dev/null 2>&1; then PKG=dnf;  APACHE=httpd
elif command -v yum     >/dev/null 2>&1; then PKG=yum;  APACHE=httpd
else die "Unsupported distribution: need apt, dnf or yum."
fi
info "Detected package manager: $PKG"

# ---------------------------------------------------------------
# Gather settings
# ---------------------------------------------------------------
read -rp "Domain pointed at this server (e.g. meetings.example.com): " DOMAIN
[ -n "$DOMAIN" ] || die "A domain is required. Browsers block camera access without HTTPS, and HTTPS needs a domain."

read -rp "Email address for the SSL certificate (renewal notices): " LE_EMAIL
[ -n "$LE_EMAIL" ] || die "An email address is required by Let's Encrypt."

SERVER_IP="$(curl -fsS --max-time 8 https://ifconfig.me 2>/dev/null || echo 'unknown')"
DOMAIN_IP="$(getent hosts "$DOMAIN" 2>/dev/null | awk '{print $1}' | head -1 || true)"

if [ "$SERVER_IP" != "unknown" ] && [ -n "$DOMAIN_IP" ] && [ "$SERVER_IP" != "$DOMAIN_IP" ]; then
  warn "DNS mismatch: $DOMAIN resolves to '$DOMAIN_IP' but this server is '$SERVER_IP'."
  warn "Certificate issuance will FAIL until the DNS A record points here."
  read -rp "Continue anyway? [y/N] " GO; [[ "$GO" =~ ^[Yy]$ ]] || exit 1
elif [ -z "$DOMAIN_IP" ]; then
  warn "$DOMAIN does not resolve yet. DNS may still be propagating."
  read -rp "Continue anyway? [y/N] " GO; [[ "$GO" =~ ^[Yy]$ ]] || exit 1
fi

TURN_SECRET="$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' \n')"
ROOM_SALT="$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')"

# ---------------------------------------------------------------
# Install packages
# ---------------------------------------------------------------
info "Installing web stack, certbot and coturn"
if [ "$PKG" = apt ]; then
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -qq
  apt-get install -y -qq apache2 php php-sqlite3 php-mbstring php-xml \
      libapache2-mod-php certbot python3-certbot-apache coturn curl
  a2enmod rewrite ssl >/dev/null
else
  $PKG install -y httpd php php-pdo php-mbstring php-xml certbot python3-certbot-apache coturn curl
  systemctl enable --now httpd
fi

# ---------------------------------------------------------------
# Deploy application files
# ---------------------------------------------------------------
info "Deploying application to $APP_DIR"
if [ "$SRC_DIR" != "$APP_DIR" ]; then
  mkdir -p "$APP_DIR"
  # Preserve an existing database if this is a redeploy.
  if [ -f "$APP_DIR/database/mms.sqlite" ]; then
    warn "Existing database found - preserving it."
    cp "$APP_DIR/database/mms.sqlite" /tmp/mms_preserve.sqlite
  fi
  cp -r "$SRC_DIR"/. "$APP_DIR"/
  if [ -f /tmp/mms_preserve.sqlite ]; then
    cp /tmp/mms_preserve.sqlite "$APP_DIR/database/mms.sqlite"
    rm -f /tmp/mms_preserve.sqlite
  fi
fi

CONFIG="$APP_DIR/config/config.php"
[ -f "$CONFIG" ] || die "config/config.php missing after copy."

# ---------------------------------------------------------------
# Write secrets and TURN settings into config.php
# ---------------------------------------------------------------
info "Writing generated secrets into config.php"
sed -i "s|^define('VIDEO_ROOM_SALT', *'[^']*');|define('VIDEO_ROOM_SALT', '${ROOM_SALT}');|" "$CONFIG"
sed -i "s|^define('TURN_URL', *'[^']*');|define('TURN_URL', 'turn:${DOMAIN}:3478');|" "$CONFIG"
sed -i "s|^define('TURN_USERNAME', *'[^']*');|define('TURN_USERNAME', 'mmsuser');|" "$CONFIG"
sed -i "s|^define('TURN_PASSWORD', *'[^']*');|define('TURN_PASSWORD', '${TURN_SECRET}');|" "$CONFIG"

grep -q "^define('TURN_URL', 'turn:${DOMAIN}:3478');" "$CONFIG" \
  || warn "Could not auto-write TURN settings - edit config/config.php by hand afterwards."

# Enable the secure session cookie now that we will be on HTTPS.
sed -i "s|// 'secure' => true,|'secure' => true,|" "$APP_DIR/app/Core/Session.php" || true

# ---------------------------------------------------------------
# Database
# ---------------------------------------------------------------
if [ ! -f "$APP_DIR/database/mms.sqlite" ]; then
  info "Creating database"
  ( cd "$APP_DIR" && php database/migrate.php )
else
  info "Database already present - skipping migration"
fi

# ---------------------------------------------------------------
# Permissions
# ---------------------------------------------------------------
info "Setting permissions"
if id -u www-data >/dev/null 2>&1; then WEBUSER=www-data; else WEBUSER=apache; fi

# Empty folders do not survive zipping - make sure they all exist before chown.
mkdir -p "$APP_DIR/storage/logs" "$APP_DIR/storage/backups" \
         "$APP_DIR/public/uploads/documents" "$APP_DIR/public/uploads/evidence"

chown -R "$WEBUSER":"$WEBUSER" "$APP_DIR"
find "$APP_DIR" -type d -exec chmod 755 {} \;
find "$APP_DIR" -type f -exec chmod 644 {} \;
# SQLite needs write access to the DIRECTORY, not just the file.
chmod 775 "$APP_DIR/database" "$APP_DIR/storage" "$APP_DIR/storage/logs" \
          "$APP_DIR/storage/backups" "$APP_DIR/public/uploads" 2>/dev/null || true
chmod 664 "$APP_DIR/database/mms.sqlite" 2>/dev/null || true

# ---------------------------------------------------------------
# Apache virtual host
# ---------------------------------------------------------------
info "Configuring Apache for $DOMAIN"
if [ "$PKG" = apt ]; then
  VHOST=/etc/apache2/sites-available/mms.conf
else
  VHOST=/etc/httpd/conf.d/mms.conf
fi

cat > "$VHOST" <<VHOSTEOF
<VirtualHost *:80>
    ServerName ${DOMAIN}
    DocumentRoot ${APP_DIR}/public

    <Directory ${APP_DIR}/public>
        AllowOverride All
        Require all granted
    </Directory>

    # Keep application internals out of the web root entirely.
    <DirectoryMatch "${APP_DIR}/(app|config|database|storage|routes)">
        Require all denied
    </DirectoryMatch>

    ErrorLog \${APACHE_LOG_DIR}/mms_error.log
    CustomLog \${APACHE_LOG_DIR}/mms_access.log combined
</VirtualHost>
VHOSTEOF

if [ "$PKG" = apt ]; then
  a2ensite mms >/dev/null
  a2dissite 000-default >/dev/null 2>&1 || true
  apache2ctl configtest
  systemctl reload apache2
else
  sed -i 's|${APACHE_LOG_DIR}|/var/log/httpd|g' "$VHOST"
  httpd -t
  systemctl reload httpd
fi

# ---------------------------------------------------------------
# Firewall
# ---------------------------------------------------------------
info "Opening firewall ports"
if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then
  ufw allow 80/tcp   >/dev/null
  ufw allow 443/tcp  >/dev/null
  ufw allow 3478/tcp >/dev/null
  ufw allow 3478/udp >/dev/null
  ufw allow 49152:65535/udp >/dev/null
  echo "  ufw rules added."
elif command -v firewall-cmd >/dev/null 2>&1; then
  firewall-cmd --permanent --add-service=http  >/dev/null
  firewall-cmd --permanent --add-service=https >/dev/null
  firewall-cmd --permanent --add-port=3478/tcp >/dev/null
  firewall-cmd --permanent --add-port=3478/udp >/dev/null
  firewall-cmd --permanent --add-port=49152-65535/udp >/dev/null
  firewall-cmd --reload >/dev/null
  echo "  firewalld rules added."
else
  warn "No active local firewall detected."
  warn "If your VPS provider has a firewall in their control panel, open: 80, 443, 3478 (TCP+UDP), 49152-65535 (UDP)."
fi

# ---------------------------------------------------------------
# HTTPS certificate
# ---------------------------------------------------------------
info "Requesting HTTPS certificate for $DOMAIN"
if certbot --apache -d "$DOMAIN" --non-interactive --agree-tos -m "$LE_EMAIL" --redirect; then
  HTTPS_OK=yes
else
  HTTPS_OK=no
  warn "Certificate issuance failed. The site will work over http:// but THE CAMERA WILL NOT."
  warn "Fix DNS so $DOMAIN points to $SERVER_IP, then re-run:  certbot --apache -d $DOMAIN"
fi

# ---------------------------------------------------------------
# coturn (TURN relay)
# ---------------------------------------------------------------
info "Configuring coturn TURN relay"
cat > /etc/turnserver.conf <<TURNEOF
listening-port=3478
fingerprint
lt-cred-mech
user=mmsuser:${TURN_SECRET}
realm=${DOMAIN}
total-quota=100
no-tls
no-dtls
no-cli
TURNEOF

if [ -f /etc/default/coturn ]; then
  sed -i 's/^#\?TURNSERVER_ENABLED=.*/TURNSERVER_ENABLED=1/' /etc/default/coturn
fi
systemctl enable coturn >/dev/null 2>&1 || true
systemctl restart coturn || warn "coturn failed to start - check: journalctl -u coturn -n 40"

# ---------------------------------------------------------------
# Done
# ---------------------------------------------------------------
SCHEME=$([ "$HTTPS_OK" = yes ] && echo https || echo http)

cat <<SUMMARY

=====================================================================
 Deployment complete
=====================================================================

  URL             ${SCHEME}://${DOMAIN}/
  Login           admin  /  Admin@12345   (you must change it on first login)

  App directory   ${APP_DIR}
  Apache vhost    ${VHOST}
  Error log       /var/log/${APACHE}/mms_error.log

  TURN relay      turn:${DOMAIN}:3478
  TURN user       mmsuser
  TURN secret     ${TURN_SECRET}
                  (already written into config/config.php - keep a copy)

  HTTPS           ${HTTPS_OK}
SUMMARY

if [ "$HTTPS_OK" != yes ]; then
cat <<'NOHTTPS'

  !! Video calls will NOT work until HTTPS is active.
     Browsers refuse camera and microphone access on plain http://
     except on localhost. Fix DNS, then re-run certbot.
NOHTTPS
fi

cat <<'NEXT'

  Next steps
  ----------
  1. Open the URL, log in, change the admin password.
  2. Create users under Administration > Users.
  3. Create a meeting, invite participants, click "Join Video Call".
  4. Test with someone on a DIFFERENT network (mobile data is a good test)
     to confirm the TURN relay is doing its job.

  Verify TURN is reachable from outside using the Trickle ICE tool:
    https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
  Add your turn: URL with the username and secret above. You should see at
  least one candidate of type "relay". If you only see "host" and "srflx",
  UDP 3478 is being blocked somewhere - check your provider's firewall.

=====================================================================
NEXT
