package aalg.crypto;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import aalg.algebra.IAlgebraicStructure;
import aalg.algebra.IElement;
import aalg.algebra.Utils;

public class HashElementKeyExtractor<T extends IElement> implements IElementKeyExtractor<T> {

	private final IAlgebraicStructure<T> structure;
	private final IHashFunction hashFunction;
	
	public HashElementKeyExtractor (final IAlgebraicStructure<T> structure, final IHashFunction hashFunction) {
		this.structure = structure;
		this.hashFunction = hashFunction;
	}
	
	@Override
	public byte[] extractKey(final T element, final int index, final int length) {
		try {
			final ByteArrayOutputStream stream = new ByteArrayOutputStream();
			Utils.writeLong(index, stream, Integer.SIZE / Byte.SIZE);
			structure.writeElement(element, stream);
			
			final byte[] hash = hashFunction.calculateHash(stream.toByteArray());
			final byte[] key = new byte[length];
			System.arraycopy(hash, 0, key, 0, length);
			
			return key;
		}
		catch (IOException ex) {
			throw new RuntimeException("Cannot calculate hash of element");
		}

	}

}
