package org.apache.solr;

import org.apache.commons.io.FileUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.BinaryResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/*
 * 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.
 */

public class TestTolerantSearch extends SolrJettyTestBase {
  
  private static SolrClient collection1;
  private static SolrClient collection2;
  private static String shard1;
  private static String shard2;
  private static File solrHome;
  
  private static File createSolrHome() throws Exception {
    File workDir = createTempDir().toFile();
    setupJettyTestHome(workDir, "collection1");
    FileUtils.copyFile(new File(SolrTestCaseJ4.TEST_HOME() + "/collection1/conf/solrconfig-tolerant-search.xml"), new File(workDir, "/collection1/conf/solrconfig.xml"));
    FileUtils.copyDirectory(new File(workDir, "collection1"), new File(workDir, "collection2"));
    return workDir;
  }
  
  
  @BeforeClass
  public static void createThings() throws Exception {
    solrHome = createSolrHome();
    createJetty(solrHome.getAbsolutePath());
    String url = jetty.getBaseUrl().toString();
    collection1 = new HttpSolrClient(url + "/collection1");
    collection2 = new HttpSolrClient(url + "/collection2");
    
    String urlCollection1 = jetty.getBaseUrl().toString() + "/" + "collection1";
    String urlCollection2 = jetty.getBaseUrl().toString() + "/" + "collection2";
    shard1 = urlCollection1.replaceAll("https?://", "");
    shard2 = urlCollection2.replaceAll("https?://", "");
    
    //create second core
    try (HttpSolrClient nodeClient = new HttpSolrClient(url)) {
      CoreAdminRequest.Create req = new CoreAdminRequest.Create();
      req.setCoreName("collection2");
      req.setConfigSet("collection1");
      nodeClient.request(req);
    }

    SolrInputDocument doc = new SolrInputDocument();
    doc.setField("id", "1");
    doc.setField("subject", "batman");
    doc.setField("title", "foo bar");
    collection1.add(doc);
    collection1.commit();
    
    doc.setField("id", "2");
    doc.setField("subject", "superman");
    collection2.add(doc);
    collection2.commit();
    
    doc = new SolrInputDocument();
    doc.setField("id", "3");
    doc.setField("subject", "aquaman");
    doc.setField("title", "foo bar");
    collection1.add(doc);
    collection1.commit();
    
  }
  
  @AfterClass
  public static void destroyThings() throws Exception {
    collection1.close();
    collection2.close();
    collection1 = null;
    collection2 = null;
    jetty.stop();
    jetty=null;
    resetExceptionIgnores();
  }
  
  @SuppressWarnings("unchecked")
  public void testGetFieldsPhaseError() throws SolrServerException, IOException {
    BadResponseWriter.failOnGetFields = true;
    BadResponseWriter.failOnGetTopIds = false;
    SolrQuery query = new SolrQuery();
    query.setQuery("subject:batman OR subject:superman");
    query.addField("id");
    query.addField("subject");
    query.set("distrib", "true");
    query.set("shards", shard1 + "," + shard2);
    query.set(ShardParams.SHARDS_INFO, "true");
    query.set("debug", "true");
    query.set("stats", "true");
    query.set("stats.field", "id");
    query.set("mlt", "true");
    query.set("mlt.fl", "title");
    query.set("mlt.count", "1");
    query.set("mlt.mintf", "0");
    query.set("mlt.mindf", "0");
    query.setHighlight(true);
    query.addFacetField("id");
    query.setFacet(true);
    
    ignoreException("Dummy exception in BadResponseWriter");
    try {
      collection1.query(query);
      fail("Should get an exception");
    } catch (Exception e) {
      //expected
    }
    query.set(ShardParams.SHARDS_TOLERANT, "true");
    QueryResponse response = collection1.query(query);
    assertTrue(response.getResponseHeader().getBooleanArg("partialResults"));
    NamedList<Object> shardsInfo = ((NamedList<Object>)response.getResponse().get(ShardParams.SHARDS_INFO));
    boolean foundError = false;
    for (int i = 0; i < shardsInfo.size(); i++) {
      if (shardsInfo.getName(i).contains("collection2")) {
        assertNotNull(((NamedList<Object>)shardsInfo.getVal(i)).get("error"));
        foundError = true;
        break;
      }
    }
    assertTrue(foundError);
    assertEquals(1, response.getResults().get(0).getFieldValue("id"));
    assertEquals("batman", response.getResults().get(0).getFirstValue("subject"));
    unIgnoreException("Dummy exception in BadResponseWriter");
  }
  
  @SuppressWarnings("unchecked")
  public void testGetTopIdsPhaseError() throws SolrServerException, IOException {
    BadResponseWriter.failOnGetTopIds = true;
    BadResponseWriter.failOnGetFields = false;
    SolrQuery query = new SolrQuery();
    query.setQuery("subject:batman OR subject:superman");
    query.addField("id");
    query.addField("subject");
    query.set("distrib", "true");
    query.set("shards", shard1 + "," + shard2);
    query.set(ShardParams.SHARDS_INFO, "true");
    query.set("debug", "true");
    query.set("stats", "true");
    query.set("stats.field", "id");
    query.set("mlt", "true");
    query.set("mlt.fl", "title");
    query.set("mlt.count", "1");
    query.set("mlt.mintf", "0");
    query.set("mlt.mindf", "0");
    query.setHighlight(true);
    query.addFacetField("id");
    query.setFacet(true);
    
    ignoreException("Dummy exception in BadResponseWriter");
    try {
      collection1.query(query);
      fail("Should get an exception");
    } catch (Exception e) {
      //expected
    }
    query.set(ShardParams.SHARDS_TOLERANT, "true");
    QueryResponse response = collection1.query(query);
    assertTrue(response.getResponseHeader().getBooleanArg("partialResults"));
    NamedList<Object> shardsInfo = ((NamedList<Object>)response.getResponse().get(ShardParams.SHARDS_INFO));
    boolean foundError = false;
    for (int i = 0; i < shardsInfo.size(); i++) {
      if (shardsInfo.getName(i).contains("collection2")) {
        assertNotNull(((NamedList<Object>)shardsInfo.getVal(i)).get("error"));
        foundError = true;
        break;
      }
    }
    assertTrue(foundError);
    
    assertEquals(1, response.getResults().get(0).getFieldValue("id"));
    assertEquals("batman", response.getResults().get(0).getFirstValue("subject"));
    unIgnoreException("Dummy exception in BadResponseWriter");
  }
  
  public static class BadResponseWriter extends BinaryResponseWriter {
    
    private static boolean failOnGetFields = false;
    private static boolean failOnGetTopIds = false;
    
    public BadResponseWriter() {
      super();
    }
    
    @Override
    public void write(OutputStream out, SolrQueryRequest req,
        SolrQueryResponse response) throws IOException {
      
      // I want to fail on the shard request, not the original user request, and only on the 
      // GET_FIELDS phase 
      if (failOnGetFields && 
          "collection2".equals(req.getCore().getName())
          && "subject:batman OR subject:superman".equals(req.getParams().get("q", ""))
          && req.getParams().get("ids") != null) {
        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, 
            "Dummy exception in BadResponseWriter");
      } else if (failOnGetTopIds 
          && "collection2".equals(req.getCore().getName())
          && "subject:batman OR subject:superman".equals(req.getParams().get("q", ""))
          && req.getParams().get("ids") == null
          && req.getParams().getBool("isShard", false) == true) {
        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, 
            "Dummy exception in BadResponseWriter");
      }
      super.write(out, req, response);
    }
    
    
  }

  
}
