/*
 * 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.oodt.xmlquery;

import java.util.List;
import java.util.StringTokenizer;
import org.apache.oodt.product.Retriever;
import java.io.InputStream;
import java.io.IOException;

// FIXME: change MIME type application/vnd.jpl.large-product?

/**
 * A <em>large</em> result is a result for <em>large</em> products.
 *
 * What is large?  Some might say large is something that exceeds most other things of
 * like kind in bulk, capacity, quantity, superficial dimensions, or number of constituent
 * units.  Large might be big, great, capacious, extensive.  Large might be opposed to
 * small; as, a large horse; a large house or room; a large lake or pool; a large jug or
 * spoon; a large vineyard; a large army; a large city.  Some might say that particularly
 * if they're named Webster.
 *
 * @author Kelly
 * @version $Revision: 1.2 $
 */
public class LargeResult extends Result {
	/**
	 * Creates a new <code>LargeResult</code> instance.
	 *
	 * @param result a <code>Result</code> value.
	 */
	public LargeResult(Result result) {
		super(result.getID(), "application/vnd.jpl.large-product", result.getProfileID(), result.getResourceID(),
			result.getHeaders(), transformMimeType(result));
		StringTokenizer st = new StringTokenizer((String) value);
		st.nextToken();
		this.size = Long.parseLong(st.nextToken());
	}

	/**
	 * Creates a new <code>LargeResult</code> instance.
	 *
	 * @param id Result ID.
	 * @param mimeType MIME type.
	 * @param profileID Profile ID.
	 * @param resourceID Resource ID.
	 * @param headers Headers.
	 * @param size Size of the product.
	 */
	public LargeResult(String id, String mimeType, String profileID, String resourceID, List headers, long size) {
		super(id, "application/vnd.jpl.large-product", profileID, resourceID, headers, mimeType + " " + size);
		this.size = size;
	}

	/**
	 * Get the size of the product.
	 *
	 * @return Its size.
	 */
	public final long getSize() {
		return size;
	}

	public final String getMimeType() {
		return new StringTokenizer((String) value).nextToken();
	}

	/**
	 * Return the result's value.
	 *
	 * @return a String.
	 * @deprecated This method always treats its value as if it were a String.  Worse,
	 * for very large results, it cannot contain the entire result in memory.  Use
	 * {@link #getInputStream} instead to perform stream processing on result data.
	 */
	public final Object getValue() {
		Object value = null;
		InputStream in = null;
		try {
			if (size > Integer.MAX_VALUE)
				throw new IllegalStateException("Cannot use getValue() for this product, result is too large; "
					+ "use LargeResult.getInputStream instead");
			int sizeToRead = (int) size;
			byte[] buf = new byte[sizeToRead];
			int index = 0;
			int num;
			in = getInputStream();
			while ((num = in.read(buf, index, sizeToRead)) != -1) {
				index += num;
				sizeToRead -= num;
				if (sizeToRead == 0) break;
			}

			// OK, this sucks.  Sucks sucks sucks.  Look, getValue is not to
			// be used anyway.  It sucks.  But dammit, there's some annoying
			// code over in EDRN which is using it when they should be using
			// getInputStream.  Basically, if you call this, you're a hoser.
			// And if you call it and you're not expecting a String, you're a
			// loser/hoser.  DEPRECATED!
			value = new String(buf);

		} catch (IOException ex) {
			throw new IllegalStateException("Unexpected IOException: " + ex.getMessage());
		} finally {
			if (in != null) try {
				in.close();
			} catch (IOException ignore) {}
		}
		return value;
	}

	/** Size of the product. */
	private long size;

	/**
	 * Get an input stream that streams the result from the product server.
	 *
	 * @return an <code>InputStream</code> value.
	 * @throws IOException if an error occurs.
	 */
	public InputStream getInputStream() throws IOException {
		return new ChunkedProductInputStream(id, retriever, size);
	}

	/**
	 * Given an existing <code>Result</code> yield its MIME type.
	 *
	 * The existing <code>Result</code> might be a <code>LargeResult</code>, in which
	 * case the real MIME type is hidden in the value.  Otherwise, it's directly in
	 * the object.
	 *
	 * @param result a <code>Result</code> value.
	 * @return The MIME type.
	 */
	private static String transformMimeType(Result result) {
		if ("application/vnd.jpl.large-product".equals(result.mimeType))
			return (String) result.value;
		else
			return result.mimeType + " 0";
	}

	/** Serial version unique ID. */
	static final long serialVersionUID = -969838775595705444L;
}
