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

import static org.assertj.core.api.Assertions.assertThat;

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

import com.arakelian.jq.ImmutableJqLibrary;
import com.arakelian.jq.ImmutableJqRequest;
import com.arakelian.jq.JqLibrary;
import com.arakelian.jq.JqRequest;
import com.arakelian.jq.JqResponse;
import com.fasterxml.jackson.databind.JsonNode;
import org.assertj.core.api.Assertions;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.lang.Identifiable;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.client.ClusterManagementServiceBuilder;
import org.apache.geode.management.configuration.Region;
import org.apache.geode.management.configuration.RegionType;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.rules.GeodeDevRestClient;
import org.apache.geode.test.junit.rules.RequiresGeodeHome;

/**
 * this test is to make sure:
 * 1. we have a test to verify the jq filter we add to the controller
 * 2. the JQFilter we added is valid
 */
public class JQFilterVerificationDUnitTest {

  @ClassRule
  public static ClusterStartupRule cluster = new ClusterStartupRule();

  private static MemberVM locator, server;
  private static ClusterManagementService cms;

  @ClassRule
  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();

  private static GeodeDevRestClient client;
  private static Map<String, JsonNode> apiWithJQFilters = new HashMap<>();
  private static JqLibrary library;

  @BeforeClass
  public static void beforeClass() throws IOException {
    locator = cluster.startLocatorVM(0, l -> l.withHttpService());
    server = cluster.startServerVM(1, locator.getPort());
    cms = ClusterManagementServiceBuilder.buildWithHostAddress()
        .setHostAddress("localhost", locator.getHttpPort()).build();
    Region region = new Region();
    region.setName("regionA");
    region.setType(RegionType.REPLICATE);
    cms.create(region);
    // create an index using CPS api since CMS doesn't support creating index yet
    locator.invoke(() -> {
      InternalConfigurationPersistenceService cps =
          ClusterStartupRule.getLocator().getConfigurationPersistenceService();
      cps.updateCacheConfig("cluster", cc -> {
        RegionConfig regionA = Identifiable.find(cc.getRegions(), "regionA");
        RegionConfig.Index index = new RegionConfig.Index();
        index.setName("index1");
        index.setFromClause("regionA");
        index.setExpression("id");
        regionA.getIndexes().add(index);
        return cc;
      });
    });

    client = new GeodeDevRestClient("/management", "localhost", locator.getHttpPort(), false);
    JsonNode jsonObject =
        client.doGetAndAssert("/v1/api-docs").getJsonObject().get("paths");
    Iterator<Map.Entry<String, JsonNode>> urls = jsonObject.fields();
    while (urls.hasNext()) {
      Map.Entry<String, JsonNode> url = urls.next();
      Iterator<Map.Entry<String, JsonNode>> methods = url.getValue().fields();
      while (methods.hasNext()) {
        Map.Entry<String, JsonNode> method = methods.next();
        // gather all the rest endpoint that has jqFilter defined.
        if (method.getValue().get("jqFilter") != null) {
          apiWithJQFilters.put(url.getKey(), method.getValue());
        }
      }
    }

    library = ImmutableJqLibrary.of();
  }

  @AfterClass
  public static void afterClass() throws Exception {
    // after all the tests are done, the map has nothing left.
    assertThat(apiWithJQFilters).hasSize(0);
  }

  @Test
  public void getMembers() throws IOException {
    String uri = "/v1/members";
    JqResponse response =
        getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"locator-0\"");
  }

  @Test
  public void getMember() throws Exception {
    String uri = "/v1/members/locator-0";
    JqResponse response = getJqResponse(uri,
        apiWithJQFilters.remove("/v1/members/{id}").get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"locator-0\"");
  }

  @Test
  public void listRegions() throws Exception {
    String uri = "/v1/regions";
    JqResponse response =
        getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"regionA\"");
  }

  JqResponse getJqResponse(String uri, String jqFilter) throws IOException {
    JsonNode jsonObject = client.doGetAndAssert(uri).getJsonObject();
    final JqRequest request = ImmutableJqRequest.builder()
        .lib(library).input(jsonObject.toString()).filter(jqFilter).build();
    return request.execute();
  }

  @Test
  public void getRegion() throws Exception {
    String uri = "/v1/regions/regionA";
    JqResponse response = getJqResponse(uri,
        apiWithJQFilters.remove("/v1/regions/{id}").get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"regionA\"");
  }

  @Test
  public void listIndex() throws Exception {
    String uri = "/v1/indexes";
    JqResponse response =
        getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
  }

  @Test
  public void listRegionIndex() throws Exception {
    String uri = "/v1/regions/regionA/indexes";
    JqResponse response = getJqResponse(uri, apiWithJQFilters
        .remove("/v1/regions/{regionName}/indexes").get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
  }

  @Test
  public void getIndex() throws Exception {
    String uri = "/v1/regions/regionA/indexes/index1";
    JqResponse response = getJqResponse(uri, apiWithJQFilters
        .remove("/v1/regions/{regionName}/indexes/{id}").get("jqFilter").textValue());
    Assertions.assertThat(response.hasErrors()).isFalse();
    System.out.println("JQ output: " + response.getOutput());
    Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
  }
}
