/*
 * 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 org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.*;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.V2Request;
import org.apache.solr.client.solrj.response.DelegationTokenResponse;
import org.apache.solr.client.solrj.response.V2Response;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.Utils;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class V2ApiIntegrationTest extends SolrCloudTestCase {
  private static String COLL_NAME = "collection1";

  @BeforeClass
  public static void createCluster() throws Exception {
    System.setProperty("managed.schema.mutable", "true");
    configureCluster(2)
        .addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud-managed").resolve("conf"))
        .configure();
    CollectionAdminRequest.createCollection(COLL_NAME, "conf1", 1, 2)
        .process(cluster.getSolrClient());
    cluster.waitForActiveCollection(COLL_NAME, 1, 2);
  }

  @Test
  public void testWelcomeMessage() throws Exception {
    V2Response res = new V2Request.Builder("").build().process(cluster.getSolrClient());
    assertEquals(0, res.getStatus());

    res = new V2Request.Builder("/_introspect").build().process(cluster.getSolrClient());
    assertEquals(0, res.getStatus());
  }

  private void testException(ResponseParser responseParser, int expectedCode, String path, String payload) throws IOException, SolrServerException {
    V2Request v2Request = new V2Request.Builder(path)
        .withMethod(SolrRequest.METHOD.POST)
        .withPayload(payload)
        .build();
    v2Request.setResponseParser(responseParser);
    BaseHttpSolrClient.RemoteSolrException ex =  expectThrows(BaseHttpSolrClient.RemoteSolrException.class,
        () -> v2Request.process(cluster.getSolrClient()));
    assertEquals(expectedCode, ex.code());
  }

  @Test
  public void testException() throws Exception {
    String notFoundPath = "/c/" + COLL_NAME + "/abccdef";
    String incorrectPayload = "{rebalance-leaders: {maxAtOnce: abc, maxWaitSeconds: xyz}}";
    testException(new XMLResponseParser(),404,
        notFoundPath, incorrectPayload);
    testException(new DelegationTokenResponse.JsonMapResponseParser(),404,
        notFoundPath, incorrectPayload);
    testException(new BinaryResponseParser(),404,
        notFoundPath, incorrectPayload);
    testException(new XMLResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
    testException(new BinaryResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
    testException(new DelegationTokenResponse.JsonMapResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
  }

  private long getStatus(V2Response response) {
    Object header = response.getResponse().get("responseHeader");
    if (header instanceof NamedList) {
      return (int) ((NamedList) header).get("status");
    } else {
      return (long) ((Map) header).get("status");
    }
  }

  @Test
  public void testIntrospect() throws Exception {
    ModifiableSolrParams params = new ModifiableSolrParams();
    params.set("command","XXXX");
    params.set("method", "POST");
    @SuppressWarnings({"rawtypes"})
    Map result = resAsMap(cluster.getSolrClient(),
        new V2Request.Builder("/c/"+COLL_NAME+"/_introspect")
            .withParams(params).build());
    assertEquals("Command not found!", Utils.getObjectByPath(result, false, "/spec[0]/commands/XXXX"));
  }

  @SuppressWarnings("rawtypes")
  @Test
  public void testWTParam() throws Exception {
    V2Request request = new V2Request.Builder("/c/" + COLL_NAME + "/get/_introspect").build();
    // TODO: If possible do this in a better way
    request.setResponseParser(new NoOpResponseParser("bleh"));

    Map resp = resAsMap(cluster.getSolrClient(), request);
    String respString = resp.toString();

    assertFalse(respString.contains("<body><h2>HTTP ERROR 500</h2>"));
    assertFalse(respString.contains("500"));
    assertFalse(respString.contains("NullPointerException"));
    assertFalse(respString.contains("<p>Problem accessing /solr/____v2/c/collection1/get/_introspect. Reason:"));
    // since no-op response writer is used, doing contains match
    assertTrue(respString.contains("/c/collection1/get"));

    // no response parser
    request.setResponseParser(null);
    resp = resAsMap(cluster.getSolrClient(), request);
    respString = resp.toString();

    assertFalse(respString.contains("<body><h2>HTTP ERROR 500</h2>"));
    assertFalse(respString.contains("<p>Problem accessing /solr/____v2/c/collection1/get/_introspect. Reason:"));
    assertEquals("/c/collection1/get", Utils.getObjectByPath(resp, true, "/spec[0]/url/paths[0]"));
    assertEquals(respString, 0, Utils.getObjectByPath(resp, true, "/responseHeader/status"));
  }

  @Test
  public void testSingleWarning() throws Exception {
    @SuppressWarnings({"rawtypes"})
    NamedList resp = cluster.getSolrClient().request(
        new V2Request.Builder("/c/"+COLL_NAME+"/_introspect").build());
    @SuppressWarnings({"rawtypes"})
    List warnings = resp.getAll("WARNING");
    assertEquals(1, warnings.size());
  }

  @Test
  public void testSetPropertyValidationOfCluster() throws IOException, SolrServerException {
    @SuppressWarnings({"rawtypes"})
    NamedList resp = cluster.getSolrClient().request(
      new V2Request.Builder("/cluster").withMethod(SolrRequest.METHOD.POST).withPayload("{set-property: {name: maxCoresPerNode, val:42}}").build());
    assertTrue(resp.toString().contains("status=0"));
    resp = cluster.getSolrClient().request(
        new V2Request.Builder("/cluster").withMethod(SolrRequest.METHOD.POST).withPayload("{set-property: {name: maxCoresPerNode, val:null}}").build());
    assertTrue(resp.toString().contains("status=0"));
  }

  @Test
  public void testCollectionsApi() throws Exception {
    CloudSolrClient client = cluster.getSolrClient();
    @SuppressWarnings({"rawtypes"})
    Map result = resAsMap(client, new V2Request.Builder("/c/"+COLL_NAME+"/get/_introspect").build());
    assertEquals("/c/collection1/get", Utils.getObjectByPath(result, true, "/spec[0]/url/paths[0]"));
    result = resAsMap(client, new V2Request.Builder("/collections/"+COLL_NAME+"/get/_introspect").build());
    assertEquals("/collections/collection1/get", Utils.getObjectByPath(result, true, "/spec[0]/url/paths[0]"));
    String tempDir = createTempDir().toFile().getPath();
    Map<String, Object> backupPayload = new HashMap<>();
    Map<String, Object> backupParams = new HashMap<>();
    backupPayload.put("backup-collection", backupParams);
    backupParams.put("name", "backup_test");
    backupParams.put("collection", COLL_NAME);
    backupParams.put("location", tempDir);
    cluster.getJettySolrRunners().forEach(j -> j.getCoreContainer().getAllowPaths().add(Paths.get(tempDir)));
    client.request(new V2Request.Builder("/c")
        .withMethod(SolrRequest.METHOD.POST)
        .withPayload(Utils.toJSONString(backupPayload))
        .build());
  }

  @SuppressWarnings({"rawtypes"})
  private Map resAsMap(CloudSolrClient client, V2Request request) throws SolrServerException, IOException {
    NamedList<Object> rsp = client.request(request);
    return rsp.asMap(100);
  }
}
