/*=============================================================================#
 # 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.rhelp.core.http.jetty;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.CompressedContentFormat;
import org.eclipse.jetty.http.HttpContent;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.ResourceContentFactory;
import org.eclipse.jetty.server.ResourceService;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rhelp.core.http.MediaTypeProvider;
import org.eclipse.statet.rhelp.core.http.ResourceHandler;


@NonNullByDefault
public class JettyResourceHandler extends ResourceService implements ResourceHandler, ResourceFactory {
	
	
	private static class JettyMimeTypes extends org.eclipse.jetty.http.MimeTypes {
		
		
		private final MediaTypeProvider defaultMediaTypes;
		
		private @Nullable MediaTypeProvider specialMediaTypes;
		
		
		public JettyMimeTypes(final MediaTypeProvider mimeTypes) {
			this.defaultMediaTypes= mimeTypes;
		}
		
		@Override
		public @Nullable String getMimeByExtension(String filename) {
			final int idx= Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
			if (idx >= 0) {
				filename= filename.substring(idx + 1);
			}
			String type= null;
			if (this.specialMediaTypes != null) {
				type= this.specialMediaTypes.getMediaTypeString(filename);
			}
			if (type == null) {
				type= this.defaultMediaTypes.getMediaTypeString(filename);
			}
			if (type == null) {
				type= super.getMimeByExtension(filename);
			}
			return type;
		}
		
	}
	
	
	private final JettyMimeTypes mediaTypes;
	
	
	public JettyResourceHandler(final MediaTypeProvider defaultTypes) {
		this.mediaTypes= new JettyMimeTypes(defaultTypes);
		setContentFactory(new ResourceContentFactory(this, this.mediaTypes,
				new CompressedContentFormat[0] ));
	}
	
	
	@Override
	public void setSpecialMediaTypes(final MediaTypeProvider types) {
		this.mediaTypes.specialMediaTypes= types;
	}
	
	@Override
	public void setCacheControl(final String value) {
		setCacheControl(new PreEncodedHttpField(HttpHeader.CACHE_CONTROL, value));
	}
	
	@Override
	public Resource getResource(final String path) {
		return new PathResource(Paths.get(path));
	}
	
	@Override
	public void doGet(final Path path,
			final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		final HttpContent content= getContentFactory().getContent(path.toString(), resp.getBufferSize());
		boolean releaseContent= true;
		try {
			if (content == null || !content.getResource().exists()) {
				notFound(req, resp);
				return;
			}
			if (content.getResource().isDirectory()) {
				resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
			}
			if (!passConditionalHeaders(req, resp, content)) {
				return;
			}
			
			Enumeration<String> reqRanges= req.getHeaders(HttpHeader.RANGE.asString());
			if (reqRanges != null && !reqRanges.hasMoreElements()) {
				reqRanges= null;
			}
			
			releaseContent= sendData(req, resp, false, content, reqRanges);
		}
		finally {
			if (releaseContent && content != null) {
				content.release();
			}
		}
	}
	
}
