/*******************************************************************************
 * Copyright (c) 2006, 2012 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.signedcontent;

import java.io.FilterInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.eclipse.osgi.signedcontent.InvalidContentException;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;

/**
 * This InputStream will calculate the digest of bytes as they are read. At the
 * end of the InputStream, it will calculate the digests and throw an exception
 * if the calculated digest do not match the expected digests.
 */
class DigestedInputStream extends FilterInputStream {
	private final MessageDigest digests[];
	private final byte result[][];
	private final BundleEntry entry;
	private final BundleFile bundleFile;
	private long remaining;

	/**
	 * Constructs an InputStream that uses another InputStream as a source and
	 * calculates the digest. At the end of the stream an exception will be
	 * thrown if the calculated digest doesn't match the passed digest.
	 * 
	 * @param in the stream to use as an input source.
	 * @param signerInfos the signers.
	 * @param results the expected digest.
	 * @throws IOException 
	 * @throws NoSuchAlgorithmException 
	 */
	DigestedInputStream(BundleEntry entry, BundleFile bundleFile, SignerInfo[] signerInfos, byte results[][], long size) throws IOException, NoSuchAlgorithmException {
		super(entry.getInputStream());
		this.entry = entry;
		this.bundleFile = bundleFile;
		this.remaining = size;
		this.digests = new MessageDigest[signerInfos.length];
		for (int i = 0; i < signerInfos.length; i++)
			this.digests[i] = MessageDigest.getInstance(signerInfos[i].getMessageDigestAlgorithm());
		this.result = results;
	}

	/**
	 * Not supported.
	 */
	@Override
	public synchronized void mark(int readlimit) {
		// Noop, we don't want to support this
	}

	/**
	 * Always returns false.
	 */
	@Override
	public boolean markSupported() {
		return false;
	}

	/**
	 * Read a byte from the InputStream. Digests are calculated on reads. At the
	 * end of the stream the calculated digests must match the expected digests.
	 * 
	 * @return the character read or -1 at end of stream.
	 * @throws IOException if there was an problem reading the byte or at the
	 *         end of the stream the calculated digests do not match the
	 *         expected digests.
	 * @see java.io.InputStream#read()
	 */
	@Override
	public int read() throws IOException {
		if (remaining <= 0)
			return -1;
		int c = super.read();
		if (c != -1) {
			for (int i = 0; i < digests.length; i++)
				digests[i].update((byte) c);
			remaining--;
		} else {
			// We hit eof so set remaining to zero
			remaining = 0;
		}
		if (remaining == 0)
			verifyDigests();
		return c;
	}

	private void verifyDigests() throws InvalidContentException {
		// Check the digest at end of file
		for (int i = 0; i < digests.length; i++) {
			byte rc[] = digests[i].digest();
			if (!MessageDigest.isEqual(result[i], rc))
				throw new InvalidContentException(NLS.bind(SignedContentMessages.File_In_Jar_Is_Tampered, entry.getName(), bundleFile.getBaseFile()), null);
		}
	}

	/**
	 * Read bytes from the InputStream. Digests are calculated on reads. At the
	 * end of the stream the calculated digests must match the expected digests.
	 * 
	 * @return the number of characters read or -1 at end of stream.
	 * @throws IOException if there was an problem reading or at the
	 *         end of the stream the calculated digests do not match the
	 *         expected digests.
	 * @see java.io.InputStream#read()
	 */
	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		if (remaining <= 0)
			return -1;
		int rc = super.read(b, off, len);
		if (rc != -1) {
			for (int i = 0; i < digests.length; i++)
				digests[i].update(b, off, rc);
			remaining -= rc;
		} else {
			// We hit eof so set remaining to zero
			remaining = 0;
		}
		if (remaining <= 0)
			verifyDigests();
		return rc;
	}

	/**
	 * Not supported.
	 * 
	 * @throws IOException always thrown if this method is called since mark/reset is not supported.
	 * @see java.io.InputStream#reset()
	 */
	@Override
	public synchronized void reset() throws IOException {
		// Throw IOException, we don't want to support this
		throw new IOException("Reset not supported"); //$NON-NLS-1$
	}

	/**
	 * This method is implemented as a read into a bitbucket.
	 */
	@Override
	public long skip(long n) throws IOException {
		byte buffer[] = new byte[4096];
		long count = 0;
		while (n - count > 0) {
			int rc = (n - count) > buffer.length ? buffer.length : (int) (n - count);
			rc = read(buffer, 0, rc);
			if (rc == -1)
				break;
			count += rc;
			n -= rc;
		}
		return count;
	}
}
