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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.SolrPing;
import org.apache.solr.client.solrj.response.SolrPingResponse;
import org.apache.solr.cloud.MiniSolrCloudCluster;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.Before;
import org.junit.BeforeClass;

public class PingRequestHandlerTest extends SolrTestCaseJ4 {
  protected int NUM_SERVERS = 5;
  protected int NUM_SHARDS = 2;
  protected int REPLICATION_FACTOR = 2;

  private final String fileName = this.getClass().getName() + ".server-enabled";
  private File healthcheckFile = null;
  private PingRequestHandler handler = null;
  
  @BeforeClass
  public static void beforeClass() throws Exception {
    initCore("solrconfig.xml", "schema.xml");
  }

  @Before
  @SuppressWarnings({"unchecked"})
  public void before() throws IOException {
    // by default, use relative file in dataDir
    healthcheckFile = new File(initAndGetDataDir(), fileName);
    String fileNameParam = fileName;

    // sometimes randomly use an absolute File path instead 
    if (random().nextBoolean()) {
      fileNameParam = healthcheckFile.getAbsolutePath();
    } 
      
    if (healthcheckFile.exists()) FileUtils.forceDelete(healthcheckFile);

    handler = new PingRequestHandler();
    @SuppressWarnings({"rawtypes"})
    NamedList initParams = new NamedList();
    initParams.add(PingRequestHandler.HEALTHCHECK_FILE_PARAM,
                   fileNameParam);
    handler.init(initParams);
    handler.inform(h.getCore());
  }
  
  @SuppressWarnings({"rawtypes"})
  public void testPingWithNoHealthCheck() throws Exception {
    
    // for this test, we don't want any healthcheck file configured at all
    handler = new PingRequestHandler();
    handler.init(new NamedList());
    handler.inform(h.getCore());

    SolrQueryResponse rsp = null;
    
    rsp = makeRequest(handler, req());
    assertEquals("OK", rsp.getValues().get("status"));
    
    rsp = makeRequest(handler, req("action","ping"));
    assertEquals("OK", rsp.getValues().get("status")); 

  }
  
  public void testEnablingServer() throws Exception {

    assertTrue(!healthcheckFile.exists());

    // first make sure that ping responds back that the service is disabled
    SolrQueryResponse sqr = makeRequest(handler, req());
    SolrException se = (SolrException) sqr.getException();
    assertEquals(
      "Response should have been replaced with a 503 SolrException.",
      se.code(), SolrException.ErrorCode.SERVICE_UNAVAILABLE.code);

    // now enable

    makeRequest(handler, req("action", "enable"));

    assertTrue(healthcheckFile.exists());
    assertNotNull(FileUtils.readFileToString(healthcheckFile, "UTF-8"));

    // now verify that the handler response with success

    SolrQueryResponse rsp = makeRequest(handler, req());
    assertEquals("OK", rsp.getValues().get("status"));

    // enable when already enabled shouldn't cause any problems
    makeRequest(handler, req("action", "enable"));
    assertTrue(healthcheckFile.exists());

  }
  public void testDisablingServer() throws Exception {

    assertTrue(! healthcheckFile.exists());
        
    healthcheckFile.createNewFile();

    // first make sure that ping responds back that the service is enabled

    SolrQueryResponse rsp = makeRequest(handler, req());
    assertEquals("OK", rsp.getValues().get("status"));

    // now disable
    
    makeRequest(handler, req("action", "disable"));
    
    assertFalse(healthcheckFile.exists());

    // now make sure that ping responds back that the service is disabled    
    SolrQueryResponse sqr = makeRequest(handler, req());
    SolrException se = (SolrException) sqr.getException();
    assertEquals(
      "Response should have been replaced with a 503 SolrException.",
      se.code(), SolrException.ErrorCode.SERVICE_UNAVAILABLE.code);
    
    // disable when already disabled shouldn't cause any problems
    makeRequest(handler, req("action", "disable"));
    assertFalse(healthcheckFile.exists());
    
  }

  
  public void testGettingStatus() throws Exception {
    SolrQueryResponse rsp = null;

    handler.handleEnable(true);
    
    rsp = makeRequest(handler, req("action", "status"));
    assertEquals("enabled", rsp.getValues().get("status"));
 
    handler.handleEnable(false);   
    
    rsp = makeRequest(handler, req("action", "status"));
    assertEquals("disabled", rsp.getValues().get("status"));
 
  }
  
  public void testBadActionRaisesException() throws Exception {
    SolrException se = expectThrows(SolrException.class, () -> makeRequest(handler, req("action", "badaction")));
    assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,se.code());
  }

 public void testPingInClusterWithNoHealthCheck() throws Exception {

    MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), buildJettyConfig("/solr"));

    final CloudSolrClient cloudSolrClient = miniCluster.getSolrClient();

    try {
      assertNotNull(miniCluster.getZkServer());
      List<JettySolrRunner> jettys = miniCluster.getJettySolrRunners();
      assertEquals(NUM_SERVERS, jettys.size());
      for (JettySolrRunner jetty : jettys) {
        assertTrue(jetty.isRunning());
      }

      // create collection
      String collectionName = "testSolrCloudCollection";
      String configName = "solrCloudCollectionConfig";
      miniCluster.uploadConfigSet(SolrTestCaseJ4.TEST_PATH().resolve("collection1").resolve("conf"), configName);
      CollectionAdminRequest.createCollection(collectionName, configName, NUM_SHARDS, REPLICATION_FACTOR)
          .setPerReplicaState(SolrCloudTestCase.USE_PER_REPLICA_STATE)
          .process(miniCluster.getSolrClient());

      // Send distributed and non-distributed ping query
      SolrPingWithDistrib reqDistrib = new SolrPingWithDistrib();
      reqDistrib.setDistrib(true);
      SolrPingResponse rsp = reqDistrib.process(cloudSolrClient, collectionName);
      assertEquals(0, rsp.getStatus()); 
      assertTrue(rsp.getResponseHeader().getBooleanArg(("zkConnected")));

      
      SolrPing reqNonDistrib = new SolrPing();
      rsp = reqNonDistrib.process(cloudSolrClient, collectionName);
      assertEquals(0, rsp.getStatus());   
      assertTrue(rsp.getResponseHeader().getBooleanArg(("zkConnected")));

    }
    finally {
      miniCluster.shutdown();
    } 
  }


  /**
   * Helper Method: Executes the request against the handler, returns 
   * the response, and closes the request.
   */
  private SolrQueryResponse makeRequest(PingRequestHandler handler,
                                        SolrQueryRequest req) 
    throws Exception {

    SolrQueryResponse rsp = new SolrQueryResponse();
    try {
      handler.handleRequestBody(req, rsp);
    } finally {
      req.close();
    }
    return rsp;
  }

  static class SolrPingWithDistrib extends SolrPing {
    public SolrPing setDistrib(boolean distrib) {   
      getParams().add("distrib", distrib ? "true" : "false");
      return this;    
    }      
  }
  

}
