/*=============================================================================#
 # Copyright (c) 2018, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.rhelp.core.server;

import java.io.InputStream;
import java.net.ConnectException;
import java.net.URI;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.BasicAuthentication;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;


@NonNullByDefault
public class JettyREnvHelpAccess extends ServerREnvHelpAccess {
	
	
	private final HttpClient httpClient;
	
	
	public JettyREnvHelpAccess(final URI url, final HttpClient httpClient) throws Exception {
		super(url);
		this.httpClient= httpClient;
		
		final String userInfo= url.getUserInfo();
		if (userInfo != null) {
			final String[] auth= userInfo.split("\\:", 2); //$NON-NLS-1$
			this.httpClient.getAuthenticationStore().addAuthenticationResult(
					new BasicAuthentication.BasicResult(createUrl(getBasePath()),
					auth[0], (auth.length == 2) ? auth[1] : "" ) ); //$NON-NLS-1$
		}
		
		this.httpClient.start();
	}
	
	
	protected void checkDataStreamResponse(final Response response) throws ResponseException {
		if (response.getStatus() != HttpServletResponse.SC_OK) {
			final String message= String.format("Http Status %1$s - %2$s",
					response.getStatus(), response.getReason() );
			switch (response.getStatus()) {
			case HttpServletResponse.SC_NOT_FOUND:
				throw new NotFoundException(message);
			}
			throw new ResponseException(message);
		}
		final String contentType= response.getHeaders().get(HttpHeader.CONTENT_TYPE);
		if (contentType == null || !contentType.startsWith(ServerApi.DS_MEDIA_TYPE_STRING)) {
			throw new ResponseException(String.format("Unexpected content type: '%1$s'.",
					contentType ));
		}
	}
	
	@Override
	protected @Nullable InputStream getDataStream(final URI url, final @Nullable String eTag,
			final String accept) throws StatusException, ResponseException {
		final Request request= this.httpClient.newRequest(url);
		if (eTag != null) {
			request.header(HttpHeader.IF_NONE_MATCH, eTag);
		}
		request.accept(accept);
		
		return doGetDataStream(request, (eTag != null));
	}
	
	@Override
	protected InputStream getDataStream(final URI url, final String[] params, final byte[] requestData,
			final String accept) throws StatusException, ResponseException {
		final Request request= this.httpClient.newRequest(url);
		for (int i= 0; i < params.length; ) {
			request.param(params[i++], params[i++]);
		}
		request.method(HttpMethod.POST);
		request.content(new BytesContentProvider(ServerApi.DS_MEDIA_TYPE_STRING, requestData));
		
		request.accept(accept);
		
		return doGetDataStream(request, false);
	}
	
	private @Nullable InputStream doGetDataStream(final Request request, final boolean notModified)
			throws StatusException, ResponseException {
		
		final InputStreamResponseListener listener= new InputStreamResponseListener();
		request.send(listener);
		
		try {
			final Response response= listener.get(20, TimeUnit.SECONDS);
			if (notModified && response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED) {
				return null;
			}
			checkDataStreamResponse(response);
			return listener.getInputStream();
		}
		catch (final InterruptedException | CancellationException e) {
			request.abort(e);
			throw onCancelled();
		}
		catch (final TimeoutException e) {
			request.abort(e);
			throw onTimeout(e);
		}
		catch (final ExecutionException e) {
			if (e.getCause() instanceof TimeoutException) {
				request.abort(e.getCause());
				throw onTimeout(e.getCause());
			}
			if (e.getCause() instanceof ConnectException) {
				request.abort(e.getCause());
				throw onConnectError(e.getCause());
			}
			request.abort(e);
			throw onFailed(e);
		}
	}
	
	@Override
	protected byte[] getDataStreamBytes(final URI url, final String[] params,
			final String accept,
			final int timeout, final @Nullable ProgressMonitor m) throws StatusException, ResponseException {
		final Request request= this.httpClient.newRequest(url);
		for (int i= 0; i < params.length; ) {
			request.param(params[i++], params[i++]);
		}
		
		request.accept(accept);
		if (timeout != -1) {
			request.timeout(timeout, TimeUnit.SECONDS);
		}
		
		final FutureResponseListener listener= new FutureResponseListener(request);
		request.send(listener);
		
		while (true) {
			try {
				final ContentResponse response= (m != null) ?
						listener.get(100, TimeUnit.MILLISECONDS) :
						listener.get();
				checkDataStreamResponse(response);
				return response.getContent();
			}
			catch (final TimeoutException e) {
				if (m.isCanceled()) {
					listener.cancel(true);
					throw onCancelled();
				}
				continue;
			}
			catch (final InterruptedException | CancellationException e) {
				request.abort(e);
				if (m != null) {
					m.setCanceled(true);
				}
				throw onCancelled();
			}
			catch (final ExecutionException e) {
				if (e.getCause() instanceof TimeoutException) {
					request.abort(e.getCause());
					throw onTimeout(e.getCause());
				}
				if (e.getCause() instanceof ConnectException) {
					request.abort(e.getCause());
					throw onConnectError(e.getCause());
				}
				request.abort(e);
				throw onFailed(e);
			}
		}
	}
	
}
