/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
package org.apache.hc.core5.http2.examples;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EndpointDetails;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.Message;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
import org.apache.hc.core5.http.message.BasicHttpResponse;
import org.apache.hc.core5.http.nio.AsyncEntityConsumer;
import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
import org.apache.hc.core5.http.nio.support.BasicResponseProducer;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2ServerBootstrap;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.net.WWWFormCodec;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
import org.apache.hc.core5.util.TimeValue;

/**
 * Example HTTP2 server that reads an entity body and responds back with a greeting.
 *
 * <pre>
 * {@code
 * $ curl  -id name=bob localhost:8080
 * HTTP/1.1 200 OK
 * Date: Sat, 25 May 2019 03:44:49 GMT
 * Server: Apache-HttpCore/5.0-beta8-SNAPSHOT (Java/1.8.0_202)
 * Transfer-Encoding: chunked
 * Content-Type: text/plain; charset=ISO-8859-1
 *
 * Hello bob
 * }</pre>
 * <p>
 * This examples uses a {@link AbstractServerExchangeHandler} for the basic request / response processing cycle.
 */
public class H2GreetingServer {
    public static void main(final String[] args) throws ExecutionException, InterruptedException {
        int port = 8080;
        if (args.length >= 1) {
            port = Integer.parseInt(args[0]);
        }

        final HttpAsyncServer server = H2ServerBootstrap.bootstrap()
                .setH2Config(H2Config.DEFAULT)
                .setIOReactorConfig(IOReactorConfig.DEFAULT)
                .setVersionPolicy(HttpVersionPolicy.NEGOTIATE) // fallback to HTTP/1 as needed

                // wildcard path matcher:
                .register("*", CustomServerExchangeHandler::new)
                .create();


        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("HTTP server shutting down");
            server.close(CloseMode.GRACEFUL);
        }));

        server.start();
        final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
        final ListenerEndpoint listenerEndpoint = future.get();
        System.out.println("Listening on " + listenerEndpoint.getAddress());
        server.awaitShutdown(TimeValue.ofDays(Long.MAX_VALUE));
    }

    static class CustomServerExchangeHandler extends AbstractServerExchangeHandler<Message<HttpRequest, String>> {


        @Override
        protected AsyncRequestConsumer<Message<HttpRequest, String>> supplyConsumer(
                final HttpRequest request,
                final EntityDetails entityDetails,
                final HttpContext context) {
            // if there's no body don't try to parse entity:
            AsyncEntityConsumer<String> entityConsumer = new DiscardingEntityConsumer<>();

            if (entityDetails != null) {
                entityConsumer = new StringAsyncEntityConsumer();
            }
            //noinspection unchecked
            return new BasicRequestConsumer<>(entityConsumer);

        }

        @Override
        protected void handle(final Message<HttpRequest, String> requestMessage,
                              final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
                              final HttpContext context) throws HttpException, IOException {

            final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
            final EndpointDetails endpoint = coreContext.getEndpointDetails();
            final HttpRequest req = requestMessage.getHead();
            final String httpEntity = requestMessage.getBody();

            // generic success response:
            final HttpResponse resp = new BasicHttpResponse(200);

            // recording the request
            System.out.printf("[%s] %s %s %s%n", new Date(),
                    endpoint.getRemoteAddress(),
                    req.getMethod(),
                    req.getPath());

            // Request without an entity - GET/HEAD/DELETE
            if (httpEntity == null) {
                responseTrigger.submitResponse(
                        new BasicResponseProducer(resp), context);
                return;
            }

            // Request with an entity - POST/PUT
            final Header cth = req.getHeader(HttpHeaders.CONTENT_TYPE);
            final ContentType contentType = cth != null ? ContentType.parse(cth.getValue()) : null;
            String name = "stranger";
            if (contentType != null && contentType.isSameMimeType(ContentType.APPLICATION_FORM_URLENCODED)) {

                // decoding the form entity into key/value pairs:
                final List<NameValuePair> args = WWWFormCodec.parse(httpEntity, contentType.getCharset());
                if (!args.isEmpty()) {
                    name = args.get(0).getValue();
                }
            }

            // composing greeting:
            final String greeting = String.format("Hello %s\n", name);
            responseTrigger.submitResponse(
                    new BasicResponseProducer(resp, AsyncEntityProducers.create(greeting)), context);
        }
    }

}

