/*
 * Copyright 2008-2026 Async-IO.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.atmosphere.spring.boot.webtransport;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * Servlet filter that adds the {@code Alt-Svc} response header to advertise
 * the HTTP/3 endpoint to browsers. When a browser sees this header, it can
 * upgrade the connection to HTTP/3 and use WebTransport.
 *
 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc">Alt-Svc</a>
 */
public class AltSvcFilter implements Filter {

    private final String altSvcValue;

    private final ReactorNettyTransportServer server;

    public AltSvcFilter(int h3Port) {
        this(h3Port, null);
    }

    public AltSvcFilter(int h3Port, ReactorNettyTransportServer server) {
        this.altSvcValue = "h3=\":" + h3Port + "\"; ma=86400";
        this.server = server;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // Only advertise HTTP/3 when the sidecar is actually running
        if (response instanceof HttpServletResponse httpResponse
                && (server == null || server.isRunning())) {
            httpResponse.addHeader("Alt-Svc", altSvcValue);
        }
        chain.doFilter(request, response);
    }
}
