/*
 * Copyright (C) 2010, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.internal.storage.dfs;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.InflaterInputStream;

import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectStream;

final class LargePackedWholeObject extends ObjectLoader {
	private final int type;

	private final long size;

	private final long objectOffset;

	private final int headerLength;

	private final DfsPackFile pack;

	private final DfsObjDatabase db;

	LargePackedWholeObject(int type, long size, long objectOffset,
			int headerLength, DfsPackFile pack, DfsObjDatabase db) {
		this.type = type;
		this.size = size;
		this.objectOffset = objectOffset;
		this.headerLength = headerLength;
		this.pack = pack;
		this.db = db;
	}

	@Override
	public int getType() {
		return type;
	}

	@Override
	public long getSize() {
		return size;
	}

	@Override
	public boolean isLarge() {
		return true;
	}

	@Override
	public byte[] getCachedBytes() throws LargeObjectException {
		throw new LargeObjectException();
	}

	@Override
	public ObjectStream openStream() throws MissingObjectException, IOException {
		PackInputStream packIn;
		// ctx is closed by PackInputStream, or explicitly in the finally block
		DfsReader ctx = db.newReader();
		try {
			try {
				packIn = new PackInputStream(
						pack, objectOffset + headerLength, ctx);
				ctx = null; // owned by packIn
			} catch (IOException packGone) {
				// If the pack file cannot be pinned into the cursor, it
				// probably was repacked recently. Go find the object
				// again and open the stream from that location instead.
				ObjectId obj = pack.getReverseIdx(ctx).findObject(objectOffset);
				return ctx.open(obj, type).openStream();
			}
		} finally {
			if (ctx != null) {
				ctx.close();
			}
		}

		// Align buffer to inflater size, at a larger than default block.
		// This reduces the number of context switches from the
		// caller down into the pack stream inflation.
		int bufsz = 8192;
		InputStream in = new BufferedInputStream(
				new InflaterInputStream(packIn, packIn.ctx.inflater(), bufsz),
				bufsz);
		return new ObjectStream.Filter(type, size, in);
	}
}
