/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.pdfbox.io;

import java.io.File;
import java.io.IOException;

import junit.framework.TestCase;

/**
 * @author Stefan Mücke
 */
public class PagedMultiRandomAccessFileTest extends TestCase {

	private File testFile;
	private PagedMultiRandomAccessFile multiRandomAccessFile;

	@Override
	protected void setUp() throws Exception {
		// TODO Define a proper filename
		testFile = new File("C:\\test.data");
		RandomAccessFile raf = new RandomAccessFile(testFile, "rw");
		multiRandomAccessFile = new PagedMultiRandomAccessFile(raf);
	}

	@Override
	protected void tearDown() throws Exception {
		multiRandomAccessFile.close();
		testFile.delete();
	}

	public void testReadWrite_Bytes() throws IOException {
		int pageSize = 10;

		// Write data
		RandomAccess randomAccess = multiRandomAccessFile.getNewRandomAcess(pageSize);
		for (int i = 0; i < 100; i++) {
			randomAccess.write('1');
		}

		// Read data
		randomAccess.seek(0);
		for (int i = 0; i < 100; i++) {
			assertEquals('1', randomAccess.read());
		}
	}

	public void testReadWrite_Arrays() throws IOException {
		int pageSize = 10;

		// Write data
		RandomAccess randomAccess = multiRandomAccessFile.getNewRandomAcess(pageSize);
		byte[] data1 = new byte[] {'x', '1', '1', '1', '1', '1', '1', '1'}; // 7 bytes + 1 offset byte 
		int dataLength = 7;
		for (int i = 0; i < 100; i++) {
			randomAccess.write(data1, 1, dataLength);
		}

		// Read data; make sure we don't encounter 'x'
		randomAccess.seek(0);
		int expectedSize = dataLength * 100;
		assertEquals(expectedSize, randomAccess.length());
		for (int i = 0; i < expectedSize; i++) {
			assertEquals('1', randomAccess.read());
		}
	}

	public void testInterleavedReadWrite_Bytes() throws IOException {
		int pageSize = 10;

		// Write data
		RandomAccess randomAccess1 = multiRandomAccessFile.getNewRandomAcess(pageSize);
		RandomAccess randomAccess2 = multiRandomAccessFile.getNewRandomAcess(pageSize);
		for (int i = 0; i < 100; i++) {
			randomAccess1.write('1');
			randomAccess2.write('2');
		}

		// Read data
		randomAccess1.seek(0);
		randomAccess2.seek(0);
		for (int i = 0; i < 100; i++) {
			assertEquals('1', randomAccess1.read());
			assertEquals('2', randomAccess2.read());
		}
	}

	public void testInterleavedReadWrite_Arrays() throws IOException {
		int pageSize = 10;

		// Write data
		RandomAccess randomAccess1 = multiRandomAccessFile.getNewRandomAcess(pageSize);
		RandomAccess randomAccess2 = multiRandomAccessFile.getNewRandomAcess(pageSize);
		byte[] data1 = new byte[] {'x', '1', '1', '1', '1', '1', '1', '1'}; // 7 bytes + 1 offset byte 
		byte[] data2 = new byte[] {'-', '-', '-', '2', '2', '2', '2', '2'}; // 5 bytes + 3 offset bytes
		for (int i = 0; i < 100; i++) {
			randomAccess1.write(data1, 1, 7);
			randomAccess2.write(data2, 3, 5);
		}

		// Read data; make sure we don't encounter 'x' or '-' and that '1' and '2' don't get mixed up
		randomAccess1.seek(0);
		randomAccess2.seek(0);
		int expectedSize1 = 7 * 100;
		int expectedSize2 = 5 * 100;
		assertEquals(expectedSize1, randomAccess1.length());
		assertEquals(expectedSize2, randomAccess2.length());
		for (int i = 0; i < expectedSize1; i++) {
			assertEquals('1', randomAccess1.read());
		}
		for (int i = 0; i < expectedSize2; i++) {
			assertEquals('2', randomAccess2.read());
		}
	}

}
