/**
 * 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.solr.search;

import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.function.ValueSource;
import org.apache.solr.search.function.DocValues;

import java.util.Map;
import java.io.IOException;

public class TestIndexSearcher extends AbstractSolrTestCase {

  public String getSchemaFile() { return "schema11.xml"; }
  public String getSolrConfigFile() { return "solrconfig.xml"; }
  public String getCoreName() { return "basic"; }

  private String getStringVal(SolrQueryRequest sqr, String field, int doc) throws IOException {
    SchemaField sf = sqr.getSchema().getField(field);
    ValueSource vs = sf.getType().getValueSource(sf, null);
    Map context = ValueSource.newContext();
    vs.createWeight(context, sqr.getSearcher());
    SolrIndexReader sr = sqr.getSearcher().getReader();
    int idx = SolrIndexReader.readerIndex(doc, sr.getLeafOffsets());
    int base = sr.getLeafOffsets()[idx];
    SolrIndexReader sub = sr.getLeafReaders()[idx];
    DocValues vals = vs.getValues(context, sub);
    return vals.strVal(doc-base);
  }

  public void testReopen() throws Exception {

    assertU(adoc("id","1", "v_t","Hello Dude", "v_s","string1"));
    assertU(adoc("id","2", "v_t","Hello Yonik", "v_s","string2"));
    assertU(commit());

    SolrQueryRequest sr1 = req("q","foo");
    SolrIndexReader r1 = sr1.getSearcher().getReader();

    String sval1 = getStringVal(sr1, "v_s",0);
    assertEquals("string1", sval1);

    assertU(adoc("id","3", "v_s","{!literal}"));
    assertU(adoc("id","4", "v_s","other stuff"));
    assertU(commit());

    SolrQueryRequest sr2 = req("q","foo");
    SolrIndexReader r2 = sr2.getSearcher().getReader();

    // make sure the readers share the first segment
    // Didn't work w/ older versions of lucene2.9 going from segment -> multi
    assertEquals(r1.getLeafReaders()[0], r2.getLeafReaders()[0]);

    assertU(adoc("id","5", "v_f","3.14159"));
    assertU(adoc("id","6", "v_f","8983", "v_s","string6"));
    assertU(commit());

    SolrQueryRequest sr3 = req("q","foo");
    SolrIndexReader r3 = sr3.getSearcher().getReader();
    // make sure the readers share segments
    // assertEquals(r1.getLeafReaders()[0], r3.getLeafReaders()[0]);
    assertEquals(r2.getLeafReaders()[0], r3.getLeafReaders()[0]);
    assertEquals(r2.getLeafReaders()[1], r3.getLeafReaders()[1]);

    sr1.close();
    sr2.close();            

    // should currently be 1, but this could change depending on future index management
    int baseRefCount = r3.getRefCount();
    assertEquals(1, baseRefCount);

    assertU(commit());
    SolrQueryRequest sr4 = req("q","foo");
    SolrIndexReader r4 = sr4.getSearcher().getReader();

    // force an index change so the registered searcher won't be the one we are testing (and
    // then we should be able to test the refCount going all the way to 0
    assertU(adoc("id","7", "v_f","7574"));
    assertU(commit()); 

    // test that reader didn't change (according to equals at least... which uses the wrapped reader)
    assertEquals(r3,r4);
    assertEquals(baseRefCount+1, r4.getRefCount());
    sr3.close();
    assertEquals(baseRefCount, r4.getRefCount());
    sr4.close();
    assertEquals(baseRefCount-1, r4.getRefCount());


    SolrQueryRequest sr5 = req("q","foo");
    SolrIndexReader r5 = sr5.getSearcher().getReader();

    assertU(delI("1"));
    assertU(commit());
    SolrQueryRequest sr6 = req("q","foo");
    SolrIndexReader r6 = sr4.getSearcher().getReader();
    assertEquals(1, r6.getLeafReaders()[0].numDocs()); // only a single doc left in the first segment
    assertTrue( !r5.getLeafReaders()[0].equals(r6.getLeafReaders()[0]) );  // readers now different

    sr5.close();
    sr6.close();
  }
}
@@ -856,21 +856,8 @@
 olr.
-util.Abstract
 Solr
@@ -864,16 +864,18 @@
 TestCase
+J4
 ;%0Aimport
@@ -1061,16 +1061,46 @@
 cValues;
+%0Aimport org.junit.BeforeClass;
 %0A%0Aimport
@@ -1187,16 +1187,8 @@
 nds 
-Abstract
 Solr
@@ -1199,183 +1199,129 @@
 Case
+J4
  %7B%0A%0A  
-public String getSchemaFile() %7B return %22schema11.xml%22; %7D%0A  public String getSolrConfigFile() %7B return %22solrconfig.xml%22; %7D%0A  public String getCoreName() %7B return %22basic%22;
+@BeforeClass%0A  public static void beforeClass() throws Exception %7B%0A    initCore(%22solrconfig.xml%22,%22schema.xml%22);%0A 
  %7D%0A%0A
@@ -4314,25 +4314,25 @@
 ader r6 = sr
-4
+6
 .getSearcher

fix test typo that lead to resource leak