/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.wizards.datatransfer;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Output stream for writing ustar archive files (tar) compatible
 * with the specification in IEEE Std 1003.1-2001.
 *
 * @since 3.1
 */
public class TarOutputStream extends FilterOutputStream {
	
	private int byteswritten = 0;
	private int datapos = 0;
	private long cursize = 0;

	/**
	 * Creates a new tar output stream.
	 * 
	 * @param out the stream to write to
	 */
	public TarOutputStream(OutputStream out) {
		super(out);
	}

	/**
	 * Close the output stream and write any necessary padding.
	 */
	public void close() throws IOException {
		// Spec says to write 1024 bytes of zeros at the end.
		byte[] zeros = new byte[1024];
		cursize = 1024;
		write(zeros, 0, 1024);

		// Default block size for tar files is 10240, so we have to
		// pad the end of the file to be a multiple of this size.
		if((byteswritten % 10240) != 0) {
			int length = 10240 - (byteswritten % 10240);
			cursize = length;
			zeros = new byte[length];
			write(zeros, 0, length);
		}
		super.close();
	}

	/**
	 * Close the current entry in the tar file.  Must be called
	 * after each entry is completed.
	 * 
	 * @throws IOException
	 */
	public void closeEntry() throws IOException {
		byte[] data = new byte[512];
		int len = 512 - datapos;
		if(len > 0 && datapos > 0) {
			cursize = len;
			write(data, 0, len);
		}
	}

	/**
	 *  The checksum of a tar file header is simply the sum of the bytes in
	 *  the header.
	 * 
	 * @param header
	 * @return checksum
	 */
	private long headerChecksum(byte[] header) {
		long sum = 0;
		for(int i = 0; i < 512; i++) {
			sum += header[i] & 0xff;
		}
		return sum;
	}

	/**
	 * Adds an entry for a new file in the tar archive.
	 * 
	 * @param e TarEntry describing the file
	 * @throws IOException
	 */
	public void putNextEntry(TarEntry e) throws IOException {
		byte[] header = new byte[512];
		String filename = e.getName();
		String prefix = null;
		int pos, i;
		
		/* Split filename into name and prefix if necessary. */
		byte[] filenameBytes = filename.getBytes("UTF8"); //$NON-NLS-1$
		if (filenameBytes.length > 99) {
			int seppos = filename.lastIndexOf('/');
			if(seppos == -1) throw new IOException("filename too long"); //$NON-NLS-1$
			prefix = filename.substring(0, seppos);
			filename = filename.substring(seppos + 1);
			filenameBytes = filename.getBytes("UTF8"); //$NON-NLS-1$
			if (filenameBytes.length > 99)
				throw new IOException("filename too long"); //$NON-NLS-1$
		}
		
		/* Filename. */
		pos = 0;
		System.arraycopy(filenameBytes, 0, header, 0, filenameBytes.length);
		pos += 100;
		
		/* File mode. */
		StringBuffer mode = new StringBuffer(Long.toOctalString(e.getMode()));
		while(mode.length() < 7) mode.insert(0,'0');
		for(i = 0; i < 7; i++) {
			header[pos + i] = (byte) mode.charAt(i);
		}
		pos += 8;
		
		/* UID. */
		header[pos] = '0';
		pos += 8;
		
		/* GID. */
		header[pos] = '0';
		pos += 8;
		
		/* Length of the file. */
		String length = Long.toOctalString(e.getSize());
		for(i = 0; i < length.length(); i++) {
			header[pos + i] = (byte) length.charAt(i);
		}
		pos += 12;
		
		/* mtime */
		String mtime = Long.toOctalString(e.getTime());
		for(i = 0; i < mtime.length(); i++) {
			header[pos + i] = (byte) mtime.charAt(i);
		}
		pos += 12;
		
		/* "Blank" out the checksum. */
		for(i = 0; i < 8; i++) {
			header[pos + i] = ' ';
		}
		pos += 8;
		
		/* Link flag. */
		header[pos] = (byte) e.getFileType();
		pos += 1;

		/* Link destination. */
		pos += 100;

		/* Add ustar header. */
		String ustar = "ustar 00"; //$NON-NLS-1$
		for(i = 0; i < ustar.length(); i++) {
			header[pos + i] = (byte) ustar.charAt(i);
		}
		header[pos + 5] = 0;
		pos += 8;
		
		/* Username. */
		String uname = "nobody"; //$NON-NLS-1$
		for(i = 0; i < uname.length(); i++) {
			header[pos + i] = (byte) uname.charAt(i);
		}
		pos += 32;
		
		
		/* Group name. */
		String gname = "nobody"; //$NON-NLS-1$
		for(i = 0; i < gname.length(); i++) {
			header[pos + i] = (byte) gname.charAt(i);
		}
		pos += 32;
		
		/* Device major. */
		pos += 8;

		/* Device minor. */
		pos += 8;

		/* File prefix. */
		if(prefix != null) {
			byte[] prefixBytes = prefix.getBytes("UTF8"); //$NON-NLS-1$
			if (prefixBytes.length > 155)
				throw new IOException("prefix too large"); //$NON-NLS-1$
			System.arraycopy(prefixBytes, 0, header, pos, prefixBytes.length);
		}

		long sum = headerChecksum(header);
		pos = 100 + 8 + 8 + 8 + 12 + 12;
		String sumval = Long.toOctalString(sum);
		for(i = 0; i < sumval.length(); i++) {
			header[pos + i] = (byte) sumval.charAt(i);
		}

		cursize = 512;
		write(header, 0, 512);
		
		cursize = e.getSize();
	}

	/**
	 * Writes data for the current file into the archive.
	 */
	public void write(byte[] b, int off, int len) throws IOException {
		super.write(b, off, len);
		datapos = (datapos + len) % 512;
		byteswritten += len;
		cursize -= len;
		if(cursize < 0) {
			throw new IOException("too much data written for current file"); //$NON-NLS-1$
		}
	}
}
