/*
 * Copyright (C) 2010, Google Inc.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.http.server;

import static org.eclipse.jgit.http.server.ServletUtils.acceptsGzipEncoding;
import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP;
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;

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

import org.eclipse.jgit.util.TemporaryBuffer;

/**
 * Buffers a response, trying to gzip it if the user agent supports that.
 * <p>
 * If the response overflows the buffer, gzip is skipped and the response is
 * streamed to the client as its produced, most likely using HTTP/1.1 chunked
 * encoding. This is useful for servlets that produce mixed-mode content, where
 * smaller payloads are primarily pure text that compresses well, while much
 * larger payloads are heavily compressed binary data. {@link UploadPackServlet}
 * is one such servlet.
 */
class SmartOutputStream extends TemporaryBuffer {
	private static final int LIMIT = 32 * 1024;

	private final HttpServletRequest req;
	private final HttpServletResponse rsp;
	private boolean compressStream;
	private boolean startedOutput;

	SmartOutputStream(final HttpServletRequest req,
			final HttpServletResponse rsp,
			boolean compressStream) {
		super(LIMIT);
		this.req = req;
		this.rsp = rsp;
		this.compressStream = compressStream;
	}

	@Override
	protected OutputStream overflow() throws IOException {
		startedOutput = true;

		OutputStream out = rsp.getOutputStream();
		if (compressStream && acceptsGzipEncoding(req)) {
			rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
			out = new GZIPOutputStream(out);
		}
		return out;
	}

	@Override
	public void close() throws IOException {
		super.close();

		if (!startedOutput) {
			// If output hasn't started yet, the entire thing fit into our
			// buffer. Try to use a proper Content-Length header, and also
			// deflate the response with gzip if it will be smaller.
			TemporaryBuffer out = this;

			if (256 < out.length() && acceptsGzipEncoding(req)) {
				TemporaryBuffer gzbuf = new TemporaryBuffer.Heap(LIMIT);
				try {
					GZIPOutputStream gzip = new GZIPOutputStream(gzbuf);
					try {
						out.writeTo(gzip, null);
					} finally {
						gzip.close();
					}
					if (gzbuf.length() < out.length()) {
						out = gzbuf;
						rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
					}
				} catch (IOException err) {
					// Most likely caused by overflowing the buffer, meaning
					// its larger if it were compressed. Discard compressed
					// copy and use the original.
				}
			}

			// The Content-Length cannot overflow when cast to an int, our
			// hardcoded LIMIT constant above assures us we wouldn't store
			// more than 2 GiB of content in memory.
			rsp.setContentLength((int) out.length());
			final OutputStream os = rsp.getOutputStream();
			try {
				out.writeTo(os, null);
				os.flush();
			} finally {
				os.close();
			}
		}
	}
}
