package com.impetus.kundera.index;

import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import junit.framework.Assert;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.util.Version;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.CoreTestClient;
import com.impetus.kundera.metadata.KunderaMetadataManager;
import com.impetus.kundera.metadata.entities.EmbeddableEntity;
import com.impetus.kundera.metadata.entities.EmbeddableEntityTwo;
import com.impetus.kundera.metadata.entities.SingularEntityEmbeddable;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.query.Person;
import com.impetus.kundera.query.Person.Day;
import com.impetus.kundera.utils.LuceneCleanupUtilities;

public class IndexManagerTest
{

    private static final String LUCENE_DIR_PATH = "./lucene";
    
    private EntityManagerFactory emf;
    private EntityManager em;

    @Before
    public void setup()
    {
        emf = Persistence.createEntityManagerFactory("patest");
        em = emf.createEntityManager();
    }

    @Test
    public void testCRUD()
    {
        LuceneIndexer indexer = LuceneIndexer.getInstance(new StandardAnalyzer(Version.LUCENE_34), LUCENE_DIR_PATH);
        IndexManager ixManager = new IndexManager(indexer);

        EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(Person.class);
        Person p = new Person();
        p.setAge(32);
        p.setDay(Day.TUESDAY);
        p.setPersonId("p1");

        Assert.assertNotNull(ixManager.getIndexer());
        Assert.assertEquals(indexer, ixManager.getIndexer());
        
        ixManager.write(metadata, p);

        String luceneQuery = "+Person.AGE:32 AND +entity.class:com.impetus.kundera.query.Person";

        try
        {
            Map<String, Object> results = ixManager.search(luceneQuery, 0, 10, false);
            Assert.assertTrue(!results.isEmpty());
        }
        catch (LuceneIndexingException liex)
        {
            Assert.fail();
        }

        p.setAge(35);
        
        ixManager.update(metadata, p, null, Person.class);
        
        luceneQuery = "+Person.AGE:35 AND +entity.class:com.impetus.kundera.query.Person";
        
        try
        {
            Map<String, Object> results = ixManager.search(luceneQuery,1);
            Assert.assertTrue(!results.isEmpty());
        }
        catch (LuceneIndexingException liex)
        {
            Assert.fail();
        }
        
        // Remove indexes.
        ixManager.remove(metadata, p, "p1");
        
        luceneQuery = "+Person.AGE:32 AND +entity.class:com.impetus.kundera.query.Person";
        
        try
        {
            Map<String, Object> results = ixManager.search(luceneQuery, 0, 10, false);
            Assert.assertTrue(results.isEmpty());
        }
        catch (LuceneIndexingException liex)
        {
            Assert.fail();
        }
    }


    @Test
    public void testEmbeddable()
    {
        LuceneIndexer indexer = LuceneIndexer.getInstance(new StandardAnalyzer(Version.LUCENE_34), LUCENE_DIR_PATH);
        IndexManager ixManager = new IndexManager(indexer);

        EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(SingularEntityEmbeddable.class);
        SingularEntityEmbeddable entity = new SingularEntityEmbeddable();
        entity.setKey(1);
        entity.setName("entity");
        entity.setField("name");
        
        EmbeddableEntity embed1 = new EmbeddableEntity();
        embed1.setField("embeddedField1");
        
        EmbeddableEntityTwo embed2 = new EmbeddableEntityTwo();
        embed2.setField(1f);
        embed2.setName("name");

        entity.setEmbeddableEntity(embed1);
        entity.setEmbeddableEntityTwo(embed2);
        
        em.persist(entity);
        
        String luceneQuery = "+entity.class:com.impetus.kundera.metadata.entities.SingularEntityEmbeddable AND +SingularEntityEmbeddable.embeddedField:embeddedField1";
        
        Map<String, Object> results = ixManager.search(luceneQuery, 0, 10, false);
        
        Assert.assertFalse(results.isEmpty());
        
    }
    
    @Test
    public void testEmbeddableCustomIndexer()
    {
        try
        {
            CoreTestIndexer indexer = new CoreTestIndexer();
            IndexManager ixManager = new IndexManager(indexer);
            
            Map<String, Client> clients = (Map<String, Client>) em.getDelegate();
            CoreTestClient client = (CoreTestClient)clients.get("patest");
            client.setIndexManager(ixManager);

            EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(SingularEntityEmbeddable.class);
            SingularEntityEmbeddable entity = new SingularEntityEmbeddable();
            entity.setKey(1);
            entity.setName("entity");
            entity.setField("name");
            
            EmbeddableEntity embed1 = new EmbeddableEntity();
            embed1.setField("embeddedField1");
            
            EmbeddableEntityTwo embed2 = new EmbeddableEntityTwo();
            embed2.setField(1f);
            embed2.setName("name");

            entity.setEmbeddableEntity(embed1);
            entity.setEmbeddableEntityTwo(embed2);
            
            em.persist(entity);
        }
        catch (Exception e)
        {
            Assert.fail(e.getMessage());
        }       
    }
    
    @After
    public void tearDown()
    {
        LuceneCleanupUtilities.cleanDir(LUCENE_DIR_PATH);
    }

}

@@ -778,29 +778,137 @@
 .model.E
-ntityMetadata
+mploye;%0Aimport com.impetus.kundera.metadata.model.EntityMetadata;%0Aimport com.impetus.kundera.metadata.model.PropertyIndex
 ;%0Aimport
@@ -5700,24 +5700,611 @@
 %0A    %7D%0A    %0A
+    @Test %0A    public void testPropertyIndex()%0A    %7B%0A        try%0A        %7B%0A            PropertyIndex pi = new PropertyIndex(Employe.class.getDeclaredField(%22empName%22), %22EMP_NAME%22, %22ASC%22);%0A            pi.setBoost(1.2f);%0A            %0A            Assert.assertEquals(1.2f, pi.getBoost());%0A            Assert.assertEquals(%22ASC%22, pi.getIndexType());            %0A        %7D%0A        catch (SecurityException e)%0A        %7B%0A            %0A            Assert.fail(e.getMessage());%0A        %7D%0A        catch (NoSuchFieldException e)%0A        %7B%0A            Assert.fail(e.getMessage());%0A        %7D%0A    %7D%0A    %0A
     @After%0A 

fix for issue#342