package net.y3n20u.aeszip;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.zip.CRC32;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import static net.y3n20u.aeszip.CommonValues.*;

public class MacFilterOutputStream extends FilterOutputStream {
	
	private Mac authenticationMac;
	private CRC32 crc;
	
	public MacFilterOutputStream(OutputStream out) {
		super(out);
		try {
			authenticationMac = Mac.getInstance(AUTH_MAC_ALGORITHM);
		} catch (NoSuchAlgorithmException e) {
			throw new AesZipRuntimeException(e);
		}
		crc = new CRC32();
	}
	
	public long getCrc() {
		return crc.getValue();
	}

	public byte[] getAuthenticationCode() {
		return Arrays.copyOf(authenticationMac.doFinal(), LENGTH_AUTHENTICATION_CODE);
	}

	public void init(byte[] authenticationKey) {
		Key authKey = new SecretKeySpec(authenticationKey, AUTH_MAC_ALGORITHM);
		try {
			authenticationMac.init(authKey);
		} catch (InvalidKeyException e) {
			throw new AesZipRuntimeException(e);
		}
		crc.reset();
	}
	
	@Override
	public void write(byte[] b, int off, int len) throws IOException {
		this.out.write(b, off, len);
		crc.update(b, off, len);
		authenticationMac.update(b, off, len);
	}
}