/*
 * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.search.lucene;

import com.arsdigita.search.Search;
import com.arsdigita.tools.junit.framework.BaseTestCase;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;

import java.math.BigDecimal;

/**
 * SearchTest
 *
 * @author <a href="mailto:jorris@redhat.com">Jon Orris</a>
 *
 */
public class SearchTest extends LuceneTestCase {

    private static Logger s_log =
            Logger.getLogger(SearchTest.class);

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

    public void test() throws Exception {
        Note foo = new Note();
        foo.setName("Foo");
        foo.setText("This is a foo!");
        foo.save();
        BigDecimal fooID = foo.getID();

        Note bar = new Note();
        bar.setName("Bar");
        bar.setText("I am not Foo. I am Bar!");
        bar.save();
        BigDecimal barID = bar.getID();

        sync();

        LuceneSearch search = new LuceneSearch("Foo");
        int count = 0;
        boolean fooFound = false;
        boolean barFound = false;
        while(search.next()) {
            count++;
            BigDecimal id = search.getID();
            if (id.equals(fooID)) {
                fooFound = true;
            } else if(id.equals(bar.getID())) {
                barFound = true;
            } else {
                fail("Unknown object found! " + id + " " + search.getTitle());
            }
        }
        assertTrue("Foo not found!", fooFound);
        assertTrue("Bar not found!", barFound);
        assertTrue("Objects found multiple times: " + count, 2 == count);

        search = new LuceneSearch("Bar");
        if(search.next()) {
            BigDecimal id = search.getID();
            assertEquals("Didn't find bar???",barID, id);
        } else {
             fail("Bar not found");
        }

        if (search.next()) {
            fail("More than one object returned! " + search.getID() + " " + search.getTitle() );
        }

    }

    public void typeSearch() throws Exception {
        Note note = new Note();
        note.setName("TypeTest");
        note.setText("TypeTest");
        note.save();
        BigDecimal noteID = note.getID();

        Note other = new Note();
        other.setName("TypeTest");
        other.setText("TypeTest");
        other.save();
        BigDecimal otherID = other.getID();
        sync();

        LuceneSearch search = new LuceneSearch("TypeTest", Note.BASE_DATA_OBJECT_TYPE);
        if(search.next()) {
            BigDecimal id = search.getID();
            assertEquals("Didn't find note???",noteID, id);
            assertEquals("Types don't match!", Note.BASE_DATA_OBJECT_TYPE,search.getType());
        } else {
             fail("Note not found");
        }

        if (search.next()) {
            fail("More than one object returned! " + search.getID() + " " + search.getTitle() + " " + search.getType());
        }


        search = new LuceneSearch("TypeTest", OtherType.BASE_DATA_OBJECT_TYPE);
        if(search.next()) {
            BigDecimal id = search.getID();
            assertEquals("Didn't find Other???",otherID, id);
            assertEquals("Types don't match!", OtherType.BASE_DATA_OBJECT_TYPE,search.getType());
        } else {
             fail("Note not found");
        }

        if (search.next()) {
            fail("More than one object returned! " + search.getID() + " " + search.getTitle() + " " + search.getType());
        }

    }

    protected void setUp() throws Exception {
        super.setUp();
        if (Search.getConfig().isLuceneEnabled()) {
            cleanIndex();
            Registry reg = Registry.getInstance();
            reg.addAdapter(Note.BASE_DATA_OBJECT_TYPE, Note.adapter());

        }
    }

    protected void tearDown() throws Exception {
        if (Search.getConfig().isLuceneEnabled()) {
            cleanIndex();
            super.tearDown();
        }
    }

    private void sync() throws Exception {
        Indexer idx = new Indexer(Index.getLocation());
        idx.sync();

    }
    private void cleanIndex() throws Exception {
        synchronized (LuceneLock.getInstance()) {
            IndexWriter iw = new IndexWriter(Index.getLocation(),
                                             new StandardAnalyzer(),
                                             true);
            iw.close();

        }

    }
}
