package unit.search;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.neo4j.api.core.EmbeddedNeo;
import org.neo4j.api.core.Node;
import org.neo4j.api.core.Transaction;
import org.neo4j.tutor.search.MyRelationshipTypes;
import org.neo4j.tutor.search.SearchEngine;

public class TestSearch extends TestCase
{
	public TestSearch( String testName )
	{
		super( testName );
	}
	
	public static Test suite()
	{
		TestSuite suite = new TestSuite( TestSearch.class );
		return suite;
	}
	
	private SearchEngine searchEngine;
	private EmbeddedNeo neo;
	private Transaction tx;
	
	public void setUp()
	{
		neo = new EmbeddedNeo( MyRelationshipTypes.class, "var/search-test", 
			true );
		tx = Transaction.begin();
		searchEngine = new SearchEngine( neo );
	}
	
	public void tearDown()
	{
		tx.finish();
		neo.shutdown();
	}
	
	public void testSimpleSearch1()
	{
		Node document = neo.createNode();
		Properties props = new Properties();
		try
		{
			props.load( new FileInputStream( new File( 
				"etc/translations.properties" ) ) );
		}
		catch ( IOException e )
		{
			fail( "" + e );
		}
		searchEngine.injectTranslations( props );
		Node dog = searchEngine.getKeywordNode( "en", "dog" );
		assertTrue( dog != null );
		document.createRelationshipTo( dog, MyRelationshipTypes.HAS_KEYWORD );
		tx.success();
		tx.finish();
		tx = Transaction.begin();
		try
		{
			Node nodes[] = getNodeArray( searchEngine.searchDocuments( "sv", 
				"hund" ) );
			assertEquals( 1, nodes.length );
			assertEquals( document, nodes[0] );
		}
		finally
		{
			searchEngine.clean();
			document.delete();
			tx.success();
		}
	}
	
	public void testSimpleSearch2()
	{
		Node document1 = neo.createNode();
		Node document2 = neo.createNode();
		Properties props = new Properties();
		try
		{
			props.load( new FileInputStream( new File( 
				"etc/translations.properties" ) ) );
		}
		catch ( IOException e )
		{
			fail( "" + e );
		}
		searchEngine.injectTranslations( props );
		Node house = searchEngine.getKeywordNode( "en", "house" );
		Node hus = searchEngine.getKeywordNode( "sv", "hus" );
		assertTrue( house != null );
		document1.createRelationshipTo( house, 
			MyRelationshipTypes.HAS_KEYWORD );
		document2.createRelationshipTo( hus, MyRelationshipTypes.HAS_KEYWORD );
		tx.success();
		tx.finish();
		tx = Transaction.begin();
		try
		{
			Node nodes[] = getNodeArray( searchEngine.searchDocuments( "sv", 
				"hus" ) );
			assertEquals( 2, nodes.length );
			assertTrue( nodes[0].equals( document1 ) || 
				nodes[0].equals( document2 ) );
			assertTrue( nodes[1].equals( document1 ) || 
				nodes[1].equals( document2 ) );
		}
		finally
		{
			searchEngine.clean();
			document1.delete();
			document2.delete();
			tx.success();
		}
	}

	private Node[] getNodeArray( Iterable<Node> nodes )
	{
		List<Node> list = new ArrayList<Node>();
		for ( Node node : nodes )
		{
			list.add( node );
		}
		return list.toArray( new Node[ list.size() ] );
	}
}
