/*******************************************************************************
 * Copyright (c) 2000, 2015 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.core.tests.internal.localstore;

import java.io.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.localstore.*;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.runtime.IPath;

public class SafeChunkyInputOutputStreamTest extends LocalStoreTest {
	protected File temp;

	public SafeChunkyInputOutputStreamTest() {
		super();
	}

	public SafeChunkyInputOutputStreamTest(String name) {
		super(name);
	}

	protected boolean compare(byte[] source, byte[] target) {
		if (source.length != target.length) {
			return false;
		}
		for (int i = 0; i < target.length; i++) {
			if (source[i] != target[i]) {
				return false;
			}
		}
		return true;
	}

	protected byte[] merge(byte[] b1, byte[] b2) {
		byte[] result = new byte[b1.length + b2.length];
		for (int i = 0; i < b1.length; i++) {
			result[i] = b1[i];
		}
		for (int i = 0; i < b2.length; i++) {
			result[b1.length + i] = b2[i];
		}
		return result;
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		IPath location = getRandomLocation();
		temp = location.append("temp").toFile();
		temp.mkdirs();
		assertTrue("could not create temp directory", temp.isDirectory());
	}

	public static Test suite() {
		return new TestSuite(SafeChunkyInputOutputStreamTest.class);
	}

	@Override
	protected void tearDown() throws Exception {
		ensureDoesNotExistInFileSystem(temp.getParentFile());
		super.tearDown();
	}

	public void testBufferLimit() {
		File target = new File(temp, "target");
		Workspace.clear(target); // make sure there was nothing here before
		assertTrue("1.0", !target.exists());

		// use only one chunk but bigger than the buffer
		int bufferSize = 10024;
		byte[] chunk = getBigContents(bufferSize);
		SafeChunkyOutputStream output = null;
		try {
			output = new SafeChunkyOutputStream(target);
			try {
				output.write(chunk);
				output.succeed();
			} finally {
				output.close();
			}
		} catch (IOException e) {
			fail("2.0", e);
		}

		// read chunks
		SafeChunkyInputStream input = null;
		try {
			input = new SafeChunkyInputStream(target);
			try {
				byte[] read = new byte[chunk.length];
				assertTrue("3.0", input.read(read) == chunk.length);
				assertTrue("3.6", compare(chunk, read));
			} finally {
				input.close();
			}
		} catch (IOException e) {
			fail("3.20", e);
		}
		Workspace.clear(target); // make sure there was nothing here before
	}

	public void testFailure() {
		File target = new File(temp, "target");
		Workspace.clear(target); // make sure there was nothing here before
		assertTrue("1.0", !target.exists());

		// misc
		byte[] fakeEnd = new byte[ILocalStoreConstants.END_CHUNK.length];
		System.arraycopy(ILocalStoreConstants.END_CHUNK, 0, fakeEnd, 0, ILocalStoreConstants.END_CHUNK.length);
		fakeEnd[fakeEnd.length - 1] = 86;

		// write chunks
		byte[] chunk1 = getRandomString().getBytes();
		byte[] chunk2 = getRandomString().getBytes();
		byte[] chunk3 = getRandomString().getBytes();
		byte[] chunk4 = getRandomString().getBytes();
		byte[] chunk5 = getRandomString().getBytes();
		byte[] chunk6 = getRandomString().getBytes();
		SafeChunkyOutputStream output = null;
		try {
			output = new SafeChunkyOutputStream(target);
			try {
				output.write(chunk1);
				output.succeed();
				doNothing(output);
				output = new SafeChunkyOutputStream(target);
				// fake failure
				output.write(chunk2);
				output.write(ILocalStoreConstants.BEGIN_CHUNK); // another begin
				output.succeed();
				//
				doNothing(output);
				output = new SafeChunkyOutputStream(target);
				output.write(chunk3);
				output.succeed();
				doNothing(output);
				output = new SafeChunkyOutputStream(target);
				// fake failure
				output.write(chunk4);
				output.write(ILocalStoreConstants.END_CHUNK); // another end
				output.succeed();
				doNothing(output);
				//
				output = new SafeChunkyOutputStream(target);
				output.write(chunk5);
				output.succeed();
				// fake failure
				output.write(fakeEnd);
				output.write(chunk6);
				output.succeed();
			} finally {
				output.close();
			}
		} catch (IOException e) {
			fail("2.0", e);
		}

		// read chunks
		SafeChunkyInputStream input = null;
		try {
			input = new SafeChunkyInputStream(target);
			try {
				byte[] read1 = new byte[chunk1.length];
				//byte[] read2 = new byte[chunk2.length];
				byte[] read3 = new byte[chunk3.length];
				byte[] read4 = new byte[chunk4.length];
				byte[] read5 = new byte[chunk5.length];
				byte[] read6 = new byte[fakeEnd.length + chunk6.length];
				assertTrue("3.0", input.read(read1) == chunk1.length);
				//assert("3.1", input.read(read2) == chunk2.length);
				assertTrue("3.2", input.read(read3) == chunk3.length);
				assertTrue("3.3", input.read(read4) == chunk4.length);
				assertTrue("3.4", input.read(read5) == chunk5.length);
				assertTrue("3.5", input.read(read6) == (fakeEnd.length + chunk6.length));
				assertTrue("3.6", compare(chunk1, read1));
				//assert("3.7", compare(chunk2, read2));
				assertTrue("3.8", compare(chunk3, read3));
				assertTrue("3.9", compare(chunk4, read4));
				assertTrue("3.10", compare(chunk5, read5));
				byte[] expected = merge(fakeEnd, chunk6);
				assertTrue("3.11", compare(expected, read6));
			} finally {
				input.close();
			}
		} catch (IOException e) {
			fail("3.20", e);
		}
		Workspace.clear(target); // make sure there was nothing here before
	}

	/**
	 * This method is used to trick the java compiler to avoid reporting
	 * a warning that the stream was not closed. In this test we are intentionally
	 * not closing the stream to test recovery from failure.
	 */
	private void doNothing(SafeChunkyOutputStream output) {
	}

	public void testAlmostEmpty() {
		File target = new File(temp, "target");
		Workspace.clear(target); // make sure there was nothing here before
		assertTrue("1.0", !target.exists());

		// open the file but don't write anything.
		SafeChunkyOutputStream output = null;
		try {
			output = new SafeChunkyOutputStream(target);
		} catch (IOException e) {
			fail("1.0", e);
		} finally {
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					fail("1.1", e);
				}
			}
		}

		DataInputStream input = null;
		try {
			input = new DataInputStream(new SafeChunkyInputStream(target));
			input.readUTF();
			fail("2.0");
		} catch (EOFException e) {
			// should hit here
		} catch (IOException e) {
			fail("2.1", e);
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					fail("2.2", e);
				}
			}
		}
	}

	public void testSimple() {
		File target = new File(temp, "target");
		Workspace.clear(target); // make sure there was nothing here before
		assertTrue("1.0", !target.exists());

		// write chunks
		byte[] chunk1 = getRandomString().getBytes();
		byte[] chunk2 = getRandomString().getBytes();
		byte[] chunk3 = getRandomString().getBytes();
		byte[] chunk4 = getRandomString().getBytes();
		byte[] chunk5 = getRandomString().getBytes();
		SafeChunkyOutputStream output = null;
		try {
			output = new SafeChunkyOutputStream(target);
			try {
				output.write(chunk1);
				output.succeed();
				output.write(chunk2);
				output.succeed();
				output.write(chunk3);
				output.succeed();
				output.write(chunk4);
				output.succeed();
				output.write(chunk5);
				output.succeed();
			} finally {
				output.close();
			}
		} catch (IOException e) {
			fail("2.0", e);
		}

		// read chunks
		SafeChunkyInputStream input = null;
		try {
			input = new SafeChunkyInputStream(target);
			try {
				byte[] read1 = new byte[chunk1.length];
				byte[] read2 = new byte[chunk2.length];
				byte[] read3 = new byte[chunk3.length];
				byte[] read4 = new byte[chunk4.length];
				byte[] read5 = new byte[chunk5.length];
				assertTrue("3.0", input.read(read1) == chunk1.length);
				assertTrue("3.1", input.read(read2) == chunk2.length);
				assertTrue("3.2", input.read(read3) == chunk3.length);
				assertTrue("3.3", input.read(read4) == chunk4.length);
				assertTrue("3.4", input.read(read5) == chunk5.length);
				assertTrue("3.5", compare(chunk1, read1));
				assertTrue("3.6", compare(chunk2, read2));
				assertTrue("3.7", compare(chunk3, read3));
				assertTrue("3.8", compare(chunk4, read4));
				assertTrue("3.9", compare(chunk5, read5));
			} finally {
				input.close();
			}
		} catch (IOException e) {
			fail("3.10", e);
		}
		Workspace.clear(target); // make sure there was nothing here before
	}
}
