/*******************************************************************************
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * Contact Info:
 * 	Bruce Donald
 * 	Duke University
 * 	Department of Computer Science
 * 	Levine Science Research Center (LSRC)
 * 	Durham
 * 	NC 27708-0129 
 * 	USA
 * 	brd@cs.duke.edu
 * 
 * Copyright (C) 2011 Jeffrey W. Martin and Bruce R. Donald
 * 
 * <signature of Bruce Donald>, April 2011
 * Bruce Donald, Professor of Computer Science
 ******************************************************************************/


package edu.duke.donaldLab.jdshot.test.grid;

import java.io.EOFException;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;

import edu.duke.donaldLab.jdshot.TestMain;
import edu.duke.donaldLab.jdshot.grid.CellIterator;
import edu.duke.donaldLab.jdshot.grid.CellReader;
import edu.duke.donaldLab.jdshot.grid.CellWriter;
import edu.duke.donaldLab.jdshot.grid.GridCell;
import edu.duke.donaldLab.jdshot.test.ExtendedTestCase;

public class TestCellIO extends ExtendedTestCase
{
	private static final String TestPath = "/tmp/test.cells";
	
	public void testOneCell( )
	throws Exception
	{
		GridCell cell = getRandomGridCell();
		
		// write a cell
		CellWriter writer = new CellWriter( TestPath );
		assertEquals( 0, writer.getNumCellsWritten() );
		writer.writeCell( cell );
		assertEquals( 1, writer.getNumCellsWritten() );
		writer.close();
		
		// read the cell
		CellReader reader = new CellReader( TestPath, TestMain.getSearchContext().getSymmetry() );
		assertEquals( 0, reader.getNumCellsRead() );
		assertEquals( 1, reader.getNumCells() );
		assertTrue( reader.hasNext() );
		GridCell newCell = reader.readCell();
		assertEquals( 1, reader.getNumCellsRead() );
		assertFalse( reader.hasNext() );
		reader.close();
		
		// make sure the cells are the same!
		assertEquals( cell, newCell );
		
		cleanupTempFiles();
	}
	
	public void testManyCells( )
	throws Exception
	{
		final int NumCells = 10;
		
		// write the cells
		ArrayList<GridCell> cells = getRandomGridCells( NumCells );
		CellWriter writer = new CellWriter( TestPath );
		assertEquals( 0, writer.getNumCellsWritten() );
		for( GridCell cell : cells )
		{
			writer.writeCell( cell );
		}
		assertEquals( NumCells, writer.getNumCellsWritten() );
		writer.close();
		
		// read the cells
		CellReader reader = new CellReader( TestPath, TestMain.getSearchContext().getSymmetry() );
		assertEquals( 0, reader.getNumCellsRead() );
		assertEquals( NumCells, reader.getNumCells() );
		assertTrue( reader.hasNext() );
		Iterator<GridCell> iterCell = cells.iterator();
		try
		{
			while( true )
			{
				// make sure the cells are the same!
				GridCell newCell = reader.readCell();
				assertEquals( iterCell.next(), newCell );
			}
		}
		catch( EOFException ex )
		{
			// it's ok
			assertFalse( reader.hasNext() );
		}
		assertEquals( NumCells, reader.getNumCellsRead() );
		reader.close();
		
		cleanupTempFiles();
	}
	
	public void testIteratorArray( )
	{
		final int NumCells = 3;
		ArrayList<GridCell> cellsList = getRandomGridCells( NumCells );
		GridCell[] cells = new GridCell[cellsList.size()];
		cellsList.toArray( cells );
		
		CellIterator iter = new CellIterator( cells );
		
		assertEquals( 0, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells[0], iter.next() );
		assertEquals( 1, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells[1], iter.next() );
		assertEquals( 2, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells[2], iter.next() );
		assertEquals( 3, iter.getNumServed() );
		assertFalse( iter.hasNext() );
	}
	
	public void testIteratorList( )
	{
		final int NumCells = 3;
		ArrayList<GridCell> cells = getRandomGridCells( NumCells );
		
		CellIterator iter = new CellIterator( cells );
		
		assertEquals( 0, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 0 ), iter.next() );
		assertEquals( 1, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 1 ), iter.next() );
		assertEquals( 2, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 2 ), iter.next() );
		assertEquals( 3, iter.getNumServed() );
		assertFalse( iter.hasNext() );
	}
	
	public void testIteratorReader( )
	throws Exception
	{
		final int NumCells = 3;
		ArrayList<GridCell> cells = getRandomGridCells( NumCells );
		
		// write out the cells
		CellWriter writer = new CellWriter( TestPath );
		for( GridCell cell : cells )
		{
			writer.writeCell( cell );
		}
		writer.close();
		
		// get a reader
		CellReader reader = new CellReader( TestPath, TestMain.getSearchContext().getSymmetry() );
		
		CellIterator iter = new CellIterator( reader );
		
		assertEquals( 0, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 0 ), iter.next() );
		assertEquals( 1, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 1 ), iter.next() );
		assertEquals( 2, iter.getNumServed() );
		assertTrue( iter.hasNext() );
		assertEquals( cells.get( 2 ), iter.next() );
		assertEquals( 3, iter.getNumServed() );
		assertFalse( iter.hasNext() );
		
		cleanupTempFiles();
	}
	
	private void cleanupTempFiles( )
	{
		new File( TestPath ).delete();
	}
}
