/*
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * 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.internal.storage.file;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.DigestOutputStream;
import java.text.MessageFormat;
import java.util.List;

import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.PackedObjectInfo;
import org.eclipse.jgit.util.NB;

/**
 * Creates a table of contents to support random access by
 * {@link org.eclipse.jgit.internal.storage.file.PackFile}.
 * <p>
 * Pack index files (the <code>.idx</code> suffix in a pack file pair) provides
 * random access to any object in the pack by associating an ObjectId to the
 * byte offset within the pack where the object's data can be read.
 */
public abstract class PackIndexWriter {
	/** Magic constant indicating post-version 1 format. */
	protected static final byte[] TOC = { -1, 't', 'O', 'c' };

	/**
	 * Create a new writer for the oldest (most widely understood) format.
	 * <p>
	 * This method selects an index format that can accurate describe the
	 * supplied objects and that will be the most compatible format with older
	 * Git implementations.
	 * <p>
	 * Index version 1 is widely recognized by all Git implementations, but
	 * index version 2 (and later) is not as well recognized as it was
	 * introduced more than a year later. Index version 1 can only be used if
	 * the resulting pack file is under 4 gigabytes in size; packs larger than
	 * that limit must use index version 2.
	 *
	 * @param dst
	 *            the stream the index data will be written to. If not already
	 *            buffered it will be automatically wrapped in a buffered
	 *            stream. Callers are always responsible for closing the stream.
	 * @param objs
	 *            the objects the caller needs to store in the index. Entries
	 *            will be examined until a format can be conclusively selected.
	 * @return a new writer to output an index file of the requested format to
	 *         the supplied stream.
	 * @throws java.lang.IllegalArgumentException
	 *             no recognized pack index version can support the supplied
	 *             objects. This is likely a bug in the implementation.
	 * @see #oldestPossibleFormat(List)
	 */
	public static PackIndexWriter createOldestPossible(final OutputStream dst,
			final List<? extends PackedObjectInfo> objs) {
		return createVersion(dst, oldestPossibleFormat(objs));
	}

	/**
	 * Return the oldest (most widely understood) index format.
	 * <p>
	 * This method selects an index format that can accurate describe the
	 * supplied objects and that will be the most compatible format with older
	 * Git implementations.
	 * <p>
	 * Index version 1 is widely recognized by all Git implementations, but
	 * index version 2 (and later) is not as well recognized as it was
	 * introduced more than a year later. Index version 1 can only be used if
	 * the resulting pack file is under 4 gigabytes in size; packs larger than
	 * that limit must use index version 2.
	 *
	 * @param objs
	 *            the objects the caller needs to store in the index. Entries
	 *            will be examined until a format can be conclusively selected.
	 * @return the index format.
	 * @throws java.lang.IllegalArgumentException
	 *             no recognized pack index version can support the supplied
	 *             objects. This is likely a bug in the implementation.
	 */
	public static int oldestPossibleFormat(
			final List<? extends PackedObjectInfo> objs) {
		for (PackedObjectInfo oe : objs) {
			if (!PackIndexWriterV1.canStore(oe))
				return 2;
		}
		return 1;
	}


	/**
	 * Create a new writer instance for a specific index format version.
	 *
	 * @param dst
	 *            the stream the index data will be written to. If not already
	 *            buffered it will be automatically wrapped in a buffered
	 *            stream. Callers are always responsible for closing the stream.
	 * @param version
	 *            index format version number required by the caller. Exactly
	 *            this formatted version will be written.
	 * @return a new writer to output an index file of the requested format to
	 *         the supplied stream.
	 * @throws java.lang.IllegalArgumentException
	 *             the version requested is not supported by this
	 *             implementation.
	 */
	public static PackIndexWriter createVersion(final OutputStream dst,
			final int version) {
		switch (version) {
		case 1:
			return new PackIndexWriterV1(dst);
		case 2:
			return new PackIndexWriterV2(dst);
		default:
			throw new IllegalArgumentException(MessageFormat.format(
					JGitText.get().unsupportedPackIndexVersion,
					Integer.valueOf(version)));
		}
	}

	/** The index data stream we are responsible for creating. */
	protected final DigestOutputStream out;

	/** A temporary buffer for use during IO to {link #out}. */
	protected final byte[] tmp;

	/** The entries this writer must pack. */
	protected List<? extends PackedObjectInfo> entries;

	/** SHA-1 checksum for the entire pack data. */
	protected byte[] packChecksum;

	/**
	 * Create a new writer instance.
	 *
	 * @param dst
	 *            the stream this instance outputs to. If not already buffered
	 *            it will be automatically wrapped in a buffered stream.
	 */
	protected PackIndexWriter(OutputStream dst) {
		out = new DigestOutputStream(dst instanceof BufferedOutputStream ? dst
				: new BufferedOutputStream(dst),
				Constants.newMessageDigest());
		tmp = new byte[4 + Constants.OBJECT_ID_LENGTH];
	}

	/**
	 * Write all object entries to the index stream.
	 * <p>
	 * After writing the stream passed to the factory is flushed but remains
	 * open. Callers are always responsible for closing the output stream.
	 *
	 * @param toStore
	 *            sorted list of objects to store in the index. The caller must
	 *            have previously sorted the list using
	 *            {@link org.eclipse.jgit.transport.PackedObjectInfo}'s native
	 *            {@link java.lang.Comparable} implementation.
	 * @param packDataChecksum
	 *            checksum signature of the entire pack data content. This is
	 *            traditionally the last 20 bytes of the pack file's own stream.
	 * @throws java.io.IOException
	 *             an error occurred while writing to the output stream, or this
	 *             index format cannot store the object data supplied.
	 */
	public void write(final List<? extends PackedObjectInfo> toStore,
			final byte[] packDataChecksum) throws IOException {
		entries = toStore;
		packChecksum = packDataChecksum;
		writeImpl();
		out.flush();
	}

	/**
	 * Writes the index file to {@link #out}.
	 * <p>
	 * Implementations should go something like:
	 *
	 * <pre>
	 * writeFanOutTable();
	 * for (final PackedObjectInfo po : entries)
	 * 	writeOneEntry(po);
	 * writeChecksumFooter();
	 * </pre>
	 *
	 * <p>
	 * Where the logic for <code>writeOneEntry</code> is specific to the index
	 * format in use. Additional headers/footers may be used if necessary and
	 * the {@link #entries} collection may be iterated over more than once if
	 * necessary. Implementors therefore have complete control over the data.
	 *
	 * @throws java.io.IOException
	 *             an error occurred while writing to the output stream, or this
	 *             index format cannot store the object data supplied.
	 */
	protected abstract void writeImpl() throws IOException;

	/**
	 * Output the version 2 (and later) TOC header, with version number.
	 * <p>
	 * Post version 1 all index files start with a TOC header that makes the
	 * file an invalid version 1 file, and then includes the version number.
	 * This header is necessary to recognize a version 1 from a version 2
	 * formatted index.
	 *
	 * @param version
	 *            version number of this index format being written.
	 * @throws java.io.IOException
	 *             an error occurred while writing to the output stream.
	 */
	protected void writeTOC(int version) throws IOException {
		out.write(TOC);
		NB.encodeInt32(tmp, 0, version);
		out.write(tmp, 0, 4);
	}

	/**
	 * Output the standard 256 entry first-level fan-out table.
	 * <p>
	 * The fan-out table is 4 KB in size, holding 256 32-bit unsigned integer
	 * counts. Each count represents the number of objects within this index
	 * whose {@link org.eclipse.jgit.lib.ObjectId#getFirstByte()} matches the
	 * count's position in the fan-out table.
	 *
	 * @throws java.io.IOException
	 *             an error occurred while writing to the output stream.
	 */
	protected void writeFanOutTable() throws IOException {
		final int[] fanout = new int[256];
		for (PackedObjectInfo po : entries)
			fanout[po.getFirstByte() & 0xff]++;
		for (int i = 1; i < 256; i++)
			fanout[i] += fanout[i - 1];
		for (int n : fanout) {
			NB.encodeInt32(tmp, 0, n);
			out.write(tmp, 0, 4);
		}
	}

	/**
	 * Output the standard two-checksum index footer.
	 * <p>
	 * The standard footer contains two checksums (20 byte SHA-1 values):
	 * <ol>
	 * <li>Pack data checksum - taken from the last 20 bytes of the pack file.</li>
	 * <li>Index data checksum - checksum of all index bytes written, including
	 * the pack data checksum above.</li>
	 * </ol>
	 *
	 * @throws java.io.IOException
	 *             an error occurred while writing to the output stream.
	 */
	protected void writeChecksumFooter() throws IOException {
		out.write(packChecksum);
		out.on(false);
		out.write(out.getMessageDigest().digest());
	}
}
