#!/usr/bin/env bash
# A07 §5 — OnBridge 서비스 등록 + TLS 적용
#
# 선행 조건 (이 스크립트가 대신 해줄 수 없다):
#   1. 공유기 포트포워드 443/TCP → 192.168.10.6:443   ← 없으면 인증서 발급이 실패한다
#   2. 공유기 포트포워드  80/TCP → 192.168.10.6:80    ← 확인됨 (2026-09-01)
#
# 실행: sudo bash /opt/OnBridge/Docs/A07-deploy-tls.sh
set -euo pipefail

DOMAIN="onbridge01.iptime.org"
EMAIL="srobot2605@gmail.com"
ENVFILE="/opt/OnBridge/conf/onbridge.env"

[[ $EUID -eq 0 ]] || { echo "sudo 로 실행하세요."; exit 1; }

say() { printf '\n=== %s ===\n' "$1"; }

say "1/6  애플리케이션 서비스 등록 (A07 T-2)"
# 수동으로 띄워 둔 uvicorn이 있으면 정리한다. 8000 포트를 systemd 유닛에 넘겨야 한다.
pkill -f 'uvicorn main:app' 2>/dev/null || true
sleep 1
install -o bridge -g bridge -d /opt/OnBridge/logs/app
cp /opt/OnBridge/conf/onbridge.service /etc/systemd/system/onbridge.service
systemctl daemon-reload
systemctl enable --now onbridge
sleep 3
systemctl is-active --quiet onbridge || { journalctl -u onbridge -n 30 --no-pager; exit 1; }
echo "onbridge.service 실행 중"

say "2/6  nginx 프록시 설정 적용"
cp /etc/nginx/sites-available/onbridge "/etc/nginx/sites-available/onbridge.bak.$(date +%s)"
cp /opt/OnBridge/conf/nginx-onbridge.conf /etc/nginx/sites-available/onbridge
mkdir -p /var/www/html
nginx -t
systemctl reload nginx
echo "nginx 프록시 적용됨"

say "3/6  포트 443 외부 도달 확인"
# 인증서 발급 전에는 nginx가 443을 리슨하지 않는다. 따라서 "연결 거부(RST)"는
# 정상이며 포워딩이 살아 있다는 증거다. 진짜 실패는 "타임아웃"(패킷 폐기)뿐이다.
FWD=$(python3 - "$DOMAIN" <<'PY'
import socket, sys
s = socket.socket(); s.settimeout(8)
try:
    s.connect((sys.argv[1], 443)); print("OPEN")
except ConnectionRefusedError:
    print("FORWARDED")          # 공유기는 넘겼고, 서버에 리슨이 없을 뿐
except (socket.timeout, TimeoutError):
    print("BLOCKED")            # 공유기가 패킷을 버린다
except Exception:
    print("BLOCKED")
finally:
    s.close()
PY
)
if [[ "$FWD" == "BLOCKED" ]]; then
    cat <<'MSG'

  443 포트로 보낸 패킷이 응답 없이 사라집니다 (타임아웃).

  공유기(192.168.10.1) 관리도구에서 다음을 확인하세요:
    고급설정 → NAT/라우터 관리 → 포트포워드 설정
      규칙 이름 : OnBridge-HTTPS
      내부 IP   : 192.168.10.6
      외부 포트 : 443
      내부 포트 : 443
      프로토콜  : TCP

  규칙이 이미 있는데도 이 메시지가 나오면, 공유기가 443을 원격관리에
  쓰고 있을 수 있습니다 (고급설정 → 보안 기능 → 공유기 접속/보안 관리).

  1·2단계는 이미 적용되었으므로 재실행해도 안전합니다.

MSG
    exit 2
fi
echo "443 도달 확인 ($FWD)"

say "4/6  certbot 설치"
if ! command -v certbot >/dev/null; then
    apt-get update -qq
    apt-get install -y -qq certbot python3-certbot-nginx
fi
certbot --version

say "5/6  인증서 발급 및 HTTPS 전환"
certbot --nginx -d "$DOMAIN" \
        --non-interactive --agree-tos -m "$EMAIL" --redirect

say "6/6  Secure 쿠키 활성화 (A06 §8.1)"
# HTTPS가 적용된 뒤에야 켤 수 있다. 그전에 켜면 로그인 자체가 불가능해진다.
if grep -q '^ONBRIDGE_COOKIE_SECURE=' "$ENVFILE"; then
    sed -i 's/^ONBRIDGE_COOKIE_SECURE=.*/ONBRIDGE_COOKIE_SECURE=1/' "$ENVFILE"
else
    printf '\n# TLS 적용 후 활성화 — A06 §8.1\nONBRIDGE_COOKIE_SECURE=1\n' >> "$ENVFILE"
fi
systemctl restart onbridge
sleep 2

say "완료"
systemctl is-active onbridge nginx certbot.timer || true
echo
echo "  https://${DOMAIN}/login  으로 접속하세요."
echo "  자동 갱신 확인: systemctl status certbot.timer"
