# Synapse reverse proxy including .well-known/matrix/client
# domain synapse.m.localhost
server {
    listen                  80;
    listen                  [::]:80;
    listen                  443 ssl;
    listen                  8448 ssl;
    listen                  [::]:443 ssl;
    listen                  [::]:8448 ssl;
    server_name             synapse.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;

    # well-known config adding rtc_foci backend
    # Note well-known is currently not effective due to:
    # https://spec.matrix.org/v1.12/client-server-api/#well-known-uri the spec
    # says it must be at https://$server_name/... (implied port 443) Hence, we
    # currently rely for local development environment on deprecated config.json
    # setting for livekit_service_url
    location /.well-known/matrix/client {
        add_header Access-Control-Allow-Origin *;
        return 200 '{"m.homeserver": {"base_url": "https://synapse.m.localhost"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrix-rtc.m.localhost/livekit/jwt"}]}';
        default_type application/json;
    }

    # Reverse proxy for Matrix Synapse Homeserver
    # This is also required for development environment.
    # Reason: the lk-jwt-service uses the federation API for the openid token
    #         verification, which requires TLS
    location ~ ^(/_matrix|/_synapse/client)  {
        proxy_pass "http://homeserver:8008";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
    }
    location ~ ^(/_matrix|/_synapse/admin)  {
        proxy_pass "http://homeserver:8008";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
    }

}

# Synapse reverse proxy including .well-known/matrix/client
# domain synapse.othersite.m.localhost
server {
    listen                  80;
    listen                  [::]:80;
    listen                  443 ssl;
    listen                  8448 ssl;
    listen                  [::]:443 ssl;
    listen                  [::]:8448 ssl;
    server_name             synapse.othersite.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;

    # well-known config adding rtc_foci backend
    # Note well-known is currently not effective due to:
    # https://spec.matrix.org/v1.12/client-server-api/#well-known-uri the spec
    # says it must be at https://$server_name/... (implied port 443) Hence, we
    # currently rely for local development environment on deprecated config.json
    # setting for livekit_service_url
    location /.well-known/matrix/client {
        add_header Access-Control-Allow-Origin *;
        return 200 '{"m.homeserver": {"base_url": "https://synapse.othersite.m.localhost"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrix-rtc.othersite.m.localhost/livekit/jwt"}]}';
        default_type application/json;
    }

    # Reverse proxy for Matrix Synapse Homeserver
    # This is also required for development environment.
    # Reason: the lk-jwt-service uses the federation API for the openid token
    #         verification, which requires TLS
    location ~ ^(/_matrix|/_synapse/client)  {
        proxy_pass "http://homeserver-1:18008";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
    }

    location ~ ^(/_matrix|/_synapse/admin)  {
        proxy_pass "http://homeserver-1:18008";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
    }

}

# MatrixRTC reverse proxy
# domain matrix-rtc.m.localhost
# - MatrixRTC Authorization Service
# - LiveKit SFU websocket signaling connection
upstream jwt-auth-services {
    server auth-server:6080;
    server host.docker.internal:6080;
}

server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             matrix-rtc.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;

    http2 on;


    location ^~ /livekit/jwt/ {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      # JWT Service running at port 6080
      proxy_pass http://jwt-auth-services/;

    }

    location ^~ /livekit/sfu/ {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_send_timeout 120;
      proxy_read_timeout 120;
      proxy_buffering off;

      proxy_set_header Accept-Encoding gzip;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

      # LiveKit SFU websocket connection running at port 7880
      proxy_pass http://livekit-sfu:7880/;
    }

}

# MatrixRTC reverse proxy
# domain matrix-rtc.othersite.m.localhost
# - MatrixRTC Authorization Service
# - LiveKit SFU websocket signaling connection
server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             matrix-rtc.othersite.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;

    http2 on;


    location ^~ /livekit/jwt/ {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      # JWT Service running at port 16080
      proxy_pass http://auth-service-1:16080/;

    }

    location ^~ /livekit/sfu/ {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_send_timeout 120;
      proxy_read_timeout 120;
      proxy_buffering off;

      proxy_set_header Accept-Encoding gzip;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

      # LiveKit SFU websocket connection running at port 17880
      proxy_pass http://livekit-sfu-1:17880/;
    }

}

# Convenience reverse proxy for the call.m.localhost domain to element call
# running on the host either via
# - pnpm dev --host or
# - falling back to http (the element call docker container)
server {
    listen                  80;
    listen                  [::]:80;
    server_name             call.m.localhost;

    return 301 https://$host$request_uri;
}

server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             call.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;

    # 1. Attempt HTTPS first
    location ^~ / {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass https://host.docker.internal:3000;
      proxy_ssl_verify              off;

      # 2. Redirect specific errors (e.g., 502 Bad Gateway  or 504 Timeout)
      # to the named fallback location
      error_page 502 503 504 = @http_fallback;

    }

    # 3. Fallback location using HTTP
    location @http_fallback {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass http://host.docker.internal:8080;

    }

}

# Convenience reverse proxy app.m.localhost for element web
server {
    listen                  80;
    listen                  [::]:80;
    server_name             app.m.localhost;

    return 301 https://$host$request_uri;
}

server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             app.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;


    location ^~ / {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass http://element-web:8081;
      proxy_ssl_verify              off;

    }

}

# Convenience reverse proxy app.othersite.m.localhost for element web
server {
    listen                  80;
    listen                  [::]:80;
    server_name             app.othersite.m.localhost;

    return 301 https://$host$request_uri;
}

server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             app.othersite.m.localhost;
    ssl_certificate         /root/ssl/cert.pem;
    ssl_certificate_key     /root/ssl/key.pem;


    location ^~ / {

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass http://element-web-1:18081;
      proxy_ssl_verify              off;

    }

}
