//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.fcgi.client.http;

import java.net.URI;
import java.util.Locale;

import org.eclipse.jetty.client.HttpChannel;
import org.eclipse.jetty.client.HttpContent;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.client.HttpSender;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.fcgi.generator.ClientGenerator;
import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Jetty;

public class HttpSenderOverFCGI extends HttpSender
{
    private final ClientGenerator generator;

    public HttpSenderOverFCGI(HttpChannel channel)
    {
        super(channel);
        this.generator = new ClientGenerator(channel.getHttpDestination().getHttpClient().getByteBufferPool());
    }

    @Override
    protected HttpChannelOverFCGI getHttpChannel()
    {
        return (HttpChannelOverFCGI)super.getHttpChannel();
    }

    @Override
    protected void sendHeaders(HttpExchange exchange, HttpContent content, Callback callback)
    {
        Request request = exchange.getRequest();
        // Copy the request headers to be able to convert them properly
        HttpFields headers = new HttpFields();
        for (HttpField field : request.getHeaders())
            headers.put(field);
        HttpFields fcgiHeaders = new HttpFields();

        // FastCGI headers based on the URI
        URI uri = request.getURI();
        String path = uri == null ? request.getPath() : uri.getRawPath();
        fcgiHeaders.put(FCGI.Headers.DOCUMENT_URI, path);
        String query = uri == null ? null : uri.getRawQuery();
        fcgiHeaders.put(FCGI.Headers.QUERY_STRING, query == null ? "" : query);

        // FastCGI headers based on HTTP headers
        HttpField httpField = headers.remove(HttpHeader.AUTHORIZATION);
        if (httpField != null)
            fcgiHeaders.put(FCGI.Headers.AUTH_TYPE, httpField.getValue());
        httpField = headers.remove(HttpHeader.CONTENT_LENGTH);
        fcgiHeaders.put(FCGI.Headers.CONTENT_LENGTH, httpField == null ? "" : httpField.getValue());
        httpField = headers.remove(HttpHeader.CONTENT_TYPE);
        fcgiHeaders.put(FCGI.Headers.CONTENT_TYPE, httpField == null ? "" : httpField.getValue());

        // FastCGI headers that are not based on HTTP headers nor URI
        fcgiHeaders.put(FCGI.Headers.REQUEST_METHOD, request.getMethod());
        fcgiHeaders.put(FCGI.Headers.SERVER_PROTOCOL, request.getVersion().asString());
        fcgiHeaders.put(FCGI.Headers.GATEWAY_INTERFACE, "CGI/1.1");
        fcgiHeaders.put(FCGI.Headers.SERVER_SOFTWARE, "Jetty/" + Jetty.VERSION);

        // Translate remaining HTTP header into the HTTP_* format
        for (HttpField field : headers)
        {
            String name = field.getName();
            String fcgiName = "HTTP_" + name.replaceAll("-", "_").toUpperCase(Locale.ENGLISH);
            fcgiHeaders.add(fcgiName, field.getValue());
        }

        // Give a chance to the transport implementation to customize the FastCGI headers
        HttpClientTransportOverFCGI transport = (HttpClientTransportOverFCGI)getHttpChannel().getHttpDestination().getHttpClient().getTransport();
        transport.customize(request, fcgiHeaders);

        int id = getHttpChannel().getRequest();
        boolean hasContent = content.hasContent();
        Generator.Result headersResult = generator.generateRequestHeaders(id, fcgiHeaders,
                hasContent ? callback : Callback.NOOP);
        if (hasContent)
        {
            getHttpChannel().flush(headersResult);
        }
        else
        {
            Generator.Result noContentResult = generator.generateRequestContent(id, BufferUtil.EMPTY_BUFFER, true, callback);
            getHttpChannel().flush(headersResult, noContentResult);
        }
    }

    @Override
    protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
    {
        if (content.isConsumed())
        {
            callback.succeeded();
        }
        else
        {
            int request = getHttpChannel().getRequest();
            Generator.Result result = generator.generateRequestContent(request, content.getByteBuffer(), content.isLast(), callback);
            getHttpChannel().flush(result);
        }
    }
}
