/*
 * 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.
 */
package org.apache.openmeetings.web.util;

import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
import static org.apache.openmeetings.web.app.Application.getBean;
import static org.apache.openmeetings.web.app.WebSession.getExternalType;
import static org.apache.openmeetings.web.app.WebSession.getRecordingId;
import static org.apache.openmeetings.web.app.WebSession.getUserId;
import static org.red5.logging.Red5LoggerFactory.getLogger;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

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

import org.apache.commons.io.input.BoundedInputStream;
import org.apache.openmeetings.db.dao.record.FlvRecordingDao;
import org.apache.openmeetings.db.dao.user.OrganisationUserDao;
import org.apache.openmeetings.db.entity.record.FlvRecording;
import org.apache.openmeetings.web.app.WebSession;
import org.apache.wicket.protocol.http.servlet.ResponseIOException;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.http.WebResponse;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.IResource.Attributes;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.util.lang.Bytes;
import org.apache.wicket.util.resource.FileResourceStream;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.time.Time;
import org.slf4j.Logger;

public abstract class RecordingResourceReference extends ResourceReference {
	private static final long serialVersionUID = 1L;
	private static final Logger log = getLogger(RecordingResourceReference.class, webAppRootKey);

	public RecordingResourceReference(Class<? extends RecordingResourceReference> clazz) {
		super(clazz, "recordings");
	}

	@Override
	public IResource getResource() {
		return new AbstractResource() {
			private static final long serialVersionUID = 1L;
			private final static String ACCEPT_RANGES_HEADER = "Accept-Ranges";
			private final static String RANGE_HEADER = "Range";
			private final static String CONTENT_RANGE_HEADER = "Content-Range";
			private final static String RANGES_BYTES = "bytes";
			private File file;
			private boolean isRange = false;
			private long start = 0;
			private long end = 0;
			
			private long getChunkLength() {
				return isRange ? end - start + 1 : (file == null ? -1 : file.length());
			}
			
			private IResourceStream getResourceStream() {
				return file == null ? null : new FileResourceStream(file) {
					private static final long serialVersionUID = 2546785247219805747L;
					private transient BoundedInputStream bi;

					@Override
					public InputStream getInputStream() throws ResourceStreamNotFoundException {
						if (bi == null) {
							//bi = new BoundedInputStream(super.getInputStream(), end + 1);
							bi = new BoundedInputStream(super.getInputStream(), isRange ? end + 1 : (file == null ? -1 : file.length()));
							try {
								bi.skip(start);
							} catch (IOException e) {
								throw new ResourceStreamNotFoundException(e);
							}
						}
						return bi;
					}
					
					@Override
					public Bytes length() {
						return Bytes.bytes(getChunkLength());
					}
					
					@Override
					public void close() throws IOException {
						if (bi != null) {
							bi.close(); //also will close original stream
							bi = null;
						}
					}
					
					@Override
					public String getContentType() {
						return RecordingResourceReference.this.getContentType();
					}
				};
			}

			@Override
			protected void setResponseHeaders(ResourceResponse data, Attributes attributes) {
				Response response = attributes.getResponse();
				if (response instanceof WebResponse) {
					WebResponse webResponse = (WebResponse)response;
					webResponse.setStatus(isRange ? HttpServletResponse.SC_PARTIAL_CONTENT : HttpServletResponse.SC_OK);
				}
				super.setResponseHeaders(data, attributes);
			}

			@Override
			protected ResourceResponse newResourceResponse(Attributes attributes) {
				ResourceResponse rr = new ResourceResponse();
				FlvRecording r = getRecording(attributes);
				if (r != null) {
					isRange = false;
					file = getFile(r);
					rr.setFileName(getFileName(r));
					rr.setContentType(RecordingResourceReference.this.getContentType());
					rr.setContentDisposition(ContentDisposition.INLINE);
					rr.setLastModified(Time.millis(file.lastModified()));
					rr.getHeaders().addHeader(ACCEPT_RANGES_HEADER, RANGES_BYTES);
					String range = ((HttpServletRequest)attributes.getRequest().getContainerRequest()).getHeader(RANGE_HEADER);
					if (range != null && range.startsWith(RANGES_BYTES)) {
						String[] bounds = range.substring(RANGES_BYTES.length() + 1).split("-");
						if (bounds != null && bounds.length > 0) {
							long length = file.length();
							isRange = true;
							start = Long.parseLong(bounds[0]);
							end = bounds.length > 1 ? Long.parseLong(bounds[1]) : length - 1;
							//Content-Range: bytes 229376-232468/232469
							rr.getHeaders().addHeader(CONTENT_RANGE_HEADER, String.format("%s %d-%d/%d", RANGES_BYTES, start, end, length));
						}
					}
					rr.setContentLength(getChunkLength());
					rr.setWriteCallback(new WriteCallback() {
						@Override
						public void writeData(Attributes attributes) throws IOException {
							IResourceStream rStream = getResourceStream();
							try {
								writeStream(attributes, rStream.getInputStream());
							} catch (ResourceStreamNotFoundException e1) {
							} catch (ResponseIOException e) {
								// in case of range operations we expecting such exceptions
								if (!isRange) {
									log.error("Error while playing the stream", e);
								}
							} finally {
								rStream.close();
							}
						}
					});
				} else {
					rr.setError(HttpServletResponse.SC_NOT_FOUND);
				}
				return rr;
			}
		};
	}
	
	abstract String getContentType();
	abstract String getFileName(FlvRecording r);
	abstract File getFile(FlvRecording r);
	
	private Long getLong(StringValue id) {
		Long result = null;
		try {
			result = id.toLongObject();
		} catch(Exception e) {
			//no-op
		}
		return result;
	}
	
	private FlvRecording getRecording(Long id) {
		FlvRecording r = getBean(FlvRecordingDao.class).get(id);
		// TODO should we process public?
		// || r.getOwnerId() == 0 || r.getParentFileExplorerItemId() == null || r.getParentFileExplorerItemId() == 0
		if (r == null) {
			return r;
		}
		if (r.getOwnerId() == null || getUserId() == r.getOwnerId()) {
			return r;
		}
		if (r.getOrganization_id() == null || getBean(OrganisationUserDao.class).isUserInOrganization(r.getOrganization_id(), getUserId())) {
			return r;
		}
		//TODO external group check was added for plugin recording download
		String extType = getExternalType();
		if (extType != null && extType.equals(r.getCreator().getExternalUserType())) {
			return r;
		}
		return null;
	}
	
	private FlvRecording getRecording(Attributes attributes) {
		PageParameters params = attributes.getParameters();
		StringValue idStr = params.get("id");
		Long id = getLong(idStr);
		WebSession ws = WebSession.get();
		if (id != null && ws.isSignedIn()) {
			return getRecording(id);
		} else {
			ws.invalidate();
			if (ws.signIn(idStr.toString())) {
				return getRecording(getRecordingId());
			}
		}
		return null;
	}
}
