/*
 * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.netty.httpserver;

import java.net.URI;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpMessage;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
import io.netty.handler.codec.http2.Http2CodecUtil;
import io.netty.handler.codec.http2.Http2MultiplexCodecBuilder;
import io.netty.handler.codec.http2.Http2ServerUpgradeCodec;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.AsciiString;
import org.glassfish.jersey.server.ResourceConfig;

/**
 * Jersey {@link ChannelInitializer}.
 * <p>
 * Adds {@link HttpServerCodec}, {@link ChunkedWriteHandler} and {@link JerseyServerHandler} to the channels pipeline.
 *
 * @author Pavel Bucek
 */
class JerseyServerInitializer extends ChannelInitializer<SocketChannel> {

    private final URI baseUri;
    private final SslContext sslCtx;
    private final NettyHttpContainer container;
    private final boolean http2;
    private final ResourceConfig resourceConfig;

    /**
     * Constructor.
     *
     * @param baseUri         base {@link URI} of the container (includes context path, if any).
     * @param sslCtx          SSL context.
     * @param container       Netty container implementation.
     * @param resourceConfig  the application {@link ResourceConfig}
     */
    public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContainer container, ResourceConfig resourceConfig) {
        this(baseUri, sslCtx, container, resourceConfig, false);
    }

    /**
     * Constructor.
     *
     * @param baseUri         base {@link URI} of the container (includes context path, if any).
     * @param sslCtx          SSL context.
     * @param container       Netty container implementation.
     * @param resourceConfig  the application {@link ResourceConfig}
     * @param http2           Http/2 protocol support.
     */
    public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContainer container, ResourceConfig resourceConfig,
                                   boolean http2) {
        this.baseUri = baseUri;
        this.sslCtx = sslCtx;
        this.container = container;
        this.resourceConfig = resourceConfig;
        this.http2 = http2;
    }

    @Override
    public void initChannel(SocketChannel ch) {
        if (http2) {

            if (sslCtx != null) {
                configureSsl(ch);
            } else {
                configureClearText(ch);
            }

        } else {
            ChannelPipeline p = ch.pipeline();
            if (sslCtx != null) {
                p.addLast(sslCtx.newHandler(ch.alloc()));
            }
            p.addLast(new HttpServerCodec());
            p.addLast(new ChunkedWriteHandler());
            p.addLast(new JerseyServerHandler(baseUri, container, resourceConfig));
        }
    }

    /**
     * Configure the pipeline for TLS NPN negotiation to HTTP/2.
     */
    private void configureSsl(SocketChannel ch) {
        ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()), new HttpVersionChooser(baseUri, container, resourceConfig));
    }

    /**
     * Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.
     */
    private void configureClearText(SocketChannel ch) {
        final ChannelPipeline p = ch.pipeline();
        final HttpServerCodec sourceCodec = new HttpServerCodec();

        p.addLast(sourceCodec);
        p.addLast(new HttpServerUpgradeHandler(sourceCodec, new HttpServerUpgradeHandler.UpgradeCodecFactory() {
            @Override
            public HttpServerUpgradeHandler.UpgradeCodec newUpgradeCodec(CharSequence protocol) {
                if (AsciiString.contentEquals(Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME, protocol)) {
                    return new Http2ServerUpgradeCodec(Http2MultiplexCodecBuilder.forServer(
                                new JerseyHttp2ServerHandler(baseUri, container, resourceConfig)).build());
                } else {
                    return null;
                }
            }
        }));
        p.addLast(new SimpleChannelInboundHandler<HttpMessage>() {
            @Override
            protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws Exception {
                // If this handler is hit then no upgrade has been attempted and the client is just talking HTTP.
                // "Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)");

                ChannelPipeline pipeline = ctx.pipeline();
                ChannelHandlerContext thisCtx = pipeline.context(this);
                pipeline.addAfter(thisCtx.name(), null, new JerseyServerHandler(baseUri, container, resourceConfig));
                pipeline.replace(this, null, new ChunkedWriteHandler());
                ctx.fireChannelRead(msg);
            }
        });
    }
}
