/*
 * ====================================================================
 * 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.http.impl.io;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HeaderElements;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequestMapper;
import org.apache.hc.core5.http.HttpResponseFactory;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.impl.ServerSupport;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.HttpServerConnection;
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.io.support.BasicHttpServerExpectationDecorator;
import org.apache.hc.core5.http.io.support.BasicHttpServerRequestHandler;
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
import org.apache.hc.core5.http.message.MessageSupport;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.util.Args;

/**
 * {@code HttpService} is a server side HTTP protocol handler based on
 * the classic (blocking) I/O model.
 * <p>
 * {@code HttpService} relies on {@link HttpProcessor} to generate mandatory
 * protocol headers for all outgoing messages and apply common, cross-cutting
 * message transformations to all incoming and outgoing messages, whereas
 * individual {@link HttpRequestHandler}s are expected to implement
 * application specific content generation and processing.
 * <p>
 * {@code HttpService} uses {@link HttpRequestMapper} to map
 * matching request handler for a particular request URI of an incoming HTTP
 * request.
 *
 * @since 4.0
 */
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
public class HttpService {

    private final HttpProcessor processor;
    private final HttpServerRequestHandler requestHandler;
    private final ConnectionReuseStrategy connReuseStrategy;
    private final Http1StreamListener streamListener;

    /**
     * Create a new HTTP service.
     *
     * @param processor the processor to use on requests and responses
     * @param handlerMapper  the handler mapper
     * @param responseFactory  the response factory. If {@code null}
     *   {@link DefaultClassicHttpResponseFactory#INSTANCE} will be used.
     * @param connReuseStrategy the connection reuse strategy. If {@code null}
     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
     * @param streamListener message stream listener.
     */
    public HttpService(
            final HttpProcessor processor,
            final HttpRequestMapper<HttpRequestHandler> handlerMapper,
            final ConnectionReuseStrategy connReuseStrategy,
            final HttpResponseFactory<ClassicHttpResponse> responseFactory,
            final Http1StreamListener streamListener) {
        this(processor,
                new BasicHttpServerExpectationDecorator(new BasicHttpServerRequestHandler(handlerMapper, responseFactory)),
                connReuseStrategy,
                streamListener);
    }

    /**
     * Create a new HTTP service.
     *
     * @param processor the processor to use on requests and responses
     * @param handlerMapper  the handler mapper
     * @param connReuseStrategy the connection reuse strategy. If {@code null}
     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
     * @param responseFactory  the response factory. If {@code null}
     *   {@link DefaultClassicHttpResponseFactory#INSTANCE} will be used.
     */
    public HttpService(
            final HttpProcessor processor,
            final HttpRequestMapper<HttpRequestHandler> handlerMapper,
            final ConnectionReuseStrategy connReuseStrategy,
            final HttpResponseFactory<ClassicHttpResponse> responseFactory) {
        this(processor, handlerMapper, connReuseStrategy, responseFactory, null);
    }

    /**
     * Create a new HTTP service.
     *
     * @param processor the processor to use on requests and responses
     * @param requestHandler  the request handler.
     * @param connReuseStrategy the connection reuse strategy. If {@code null}
     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
     * @param streamListener message stream listener.
     */
    public HttpService(
            final HttpProcessor processor,
            final HttpServerRequestHandler requestHandler,
            final ConnectionReuseStrategy connReuseStrategy,
            final Http1StreamListener streamListener) {
        super();
        this.processor =  Args.notNull(processor, "HTTP processor");
        this.requestHandler =  Args.notNull(requestHandler, "Request handler");
        this.connReuseStrategy = connReuseStrategy != null ? connReuseStrategy : DefaultConnectionReuseStrategy.INSTANCE;
        this.streamListener = streamListener;
    }

    /**
     * Create a new HTTP service.
     *
     * @param processor the processor to use on requests and responses
     * @param requestHandler  the request handler.
     */
    public HttpService(
            final HttpProcessor processor, final HttpServerRequestHandler requestHandler) {
        this(processor, requestHandler, null, null);
    }

    /**
     * Handles receives one HTTP request over the given connection within the
     * given execution context and sends a response back to the client.
     *
     * @param conn the active connection to the client
     * @param context the actual execution context.
     * @throws IOException in case of an I/O error.
     * @throws HttpException in case of HTTP protocol violation or a processing
     *   problem.
     */
    public void handleRequest(
            final HttpServerConnection conn,
            final HttpContext context) throws IOException, HttpException {

        final AtomicBoolean responseSubmitted = new AtomicBoolean(false);
        try {
            final ClassicHttpRequest request = conn.receiveRequestHeader();
            if (streamListener != null) {
                streamListener.onRequestHead(conn, request);
            }
            conn.receiveRequestEntity(request);
            final ProtocolVersion transportVersion = request.getVersion();
            if (transportVersion != null) {
                context.setProtocolVersion(transportVersion);
            }
            context.setAttribute(HttpCoreContext.SSL_SESSION, conn.getSSLSession());
            context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, conn.getEndpointDetails());
            context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
            this.processor.process(request, request.getEntity(), context);

            this.requestHandler.handle(request, new HttpServerRequestHandler.ResponseTrigger() {

                @Override
                public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException {
                    if (responseSubmitted.get()) {
                        throw new HttpException("Response already submitted");
                    }
                    if (response.getCode() >= HttpStatus.SC_SUCCESS) {
                        throw new HttpException("Invalid intermediate response");
                    }
                    if (streamListener != null) {
                        streamListener.onResponseHead(conn, response);
                    }
                    conn.sendResponseHeader(response);
                    conn.flush();
                }

                @Override
                public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
                    try {
                        ServerSupport.validateResponse(response, response.getEntity());
                        context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
                        processor.process(response, response.getEntity(), context);

                        responseSubmitted.set(true);
                        conn.sendResponseHeader(response);
                        if (streamListener != null) {
                            streamListener.onResponseHead(conn, response);
                        }
                        if (MessageSupport.canResponseHaveBody(request.getMethod(), response)) {
                            conn.sendResponseEntity(response);
                        }
                        // Make sure the request content is fully consumed
                        EntityUtils.consume(request.getEntity());
                        final boolean keepAlive = connReuseStrategy.keepAlive(request, response, context);
                        if (streamListener != null) {
                            streamListener.onExchangeComplete(conn, keepAlive);
                        }
                        if (!keepAlive) {
                            conn.close();
                        }
                        conn.flush();
                    } finally {
                        response.close();
                    }
                }

            }, context);

        } catch (final HttpException ex) {
            if (responseSubmitted.get()) {
                throw ex;
            }
            try (final ClassicHttpResponse errorResponse = new BasicClassicHttpResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR)) {
                handleException(ex, errorResponse);
                errorResponse.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
                context.setAttribute(HttpCoreContext.HTTP_RESPONSE, errorResponse);
                this.processor.process(errorResponse, errorResponse.getEntity(), context);

                conn.sendResponseHeader(errorResponse);
                if (streamListener != null) {
                    streamListener.onResponseHead(conn, errorResponse);
                }
                conn.sendResponseEntity(errorResponse);
                conn.close();
            }
        }
    }

    /**
     * Handles the given exception and generates an HTTP response to be sent
     * back to the client to inform about the exceptional condition encountered
     * in the course of the request processing.
     *
     * @param ex the exception.
     * @param response the HTTP response.
     */
    protected void handleException(final HttpException ex, final ClassicHttpResponse response) {
        response.setCode(toStatusCode(ex));
        response.setEntity(new StringEntity(ServerSupport.toErrorMessage(ex), ContentType.TEXT_PLAIN));
    }

    protected int toStatusCode(final Exception ex) {
        return ServerSupport.toStatusCode(ex);
    }

}
