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

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.thisptr.jackson.jq.JsonQuery;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.prometheus.utils.Helpers;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class MetricsQueryTemplateTest {
  @Test
  public void testTemplatesApplyDuringInit() throws Exception {
    MetricsConfiguration config =
        Helpers.loadConfiguration(SolrTestCaseJ4.getFile("conf/test-config-with-templates.xml").getPath());
    List<MetricsQuery> metrics = config.getMetricsConfiguration();
    List<JsonQuery> jsonQueries = metrics.get(0).getJsonQueries();
    final int expectedJqQueriesInConfig = 6;
    assertEquals(expectedJqQueriesInConfig, jsonQueries.size());
    // JsonQuery does not implement an equals so use the string expression with whitespace collapsed to a single space
    for (int q = 0; q < jsonQueries.size(); q += 2) {
      String expected = jsonQueries.get(q + 1).toString().replaceAll("\\s+", " ").trim();
      String actual = jsonQueries.get(q).toString().replaceAll("\\s+", " ").trim();
      assertEquals(expected, actual);
    }
  }

  @Test
  public void testTemplateRegexMatchAndApply() {
    final String[] matches = new String[]{
        "$jq:jvm-item(memory_bytes,select(.key | startswith(\"memory.total.\")),object.value,\n\nGAUGE)",
        "$jq:node( client_errors_total,     select(.key | endswith(\".clientErrors\")), count )",
        "$jq:node(time_seconds_total,\nselect(.key == \"UPDATE.updateHandler.autoCommits\"), ($object.value / 1000))   ",
        "$jq:core-query( 1minRate, select(.key | endswith(\".distrib.requestTimes\")) )"
    };
    final String[] expectedApply = new String[]{
        "memory_bytes, select(.key | startswith(\"memory.total.\")), $object.value, GAUGE",
        "client_errors_total, select(.key | endswith(\".clientErrors\")), $object.value.count, COUNTER",
        "time_seconds_total, select(.key == \"UPDATE.updateHandler.autoCommits\"), ($object.value / 1000), COUNTER",
        "1minRate, select(.key | endswith(\".distrib.requestTimes\")), $object.value[\"1minRate\"], COUNTER"
    };

    MetricsQueryTemplate template =
        new MetricsQueryTemplate("test", "{UNIQUE}, {KEYSELECTOR}, {METRIC}, {TYPE}", "COUNTER");

    for (int m = 0; m < matches.length; m++) {
      Optional<Matcher> maybeMatcher = MetricsQueryTemplate.matches(matches[m]);
      assertTrue(maybeMatcher.isPresent());
      String jsonQuery = template.applyTemplate(maybeMatcher.get());
      assertEquals(expectedApply[m], jsonQuery);
    }
  }

  @Test
  public void testQueryMetricTemplate() throws Exception {
    Document config =
        DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(SolrTestCaseJ4.getFile("conf/test-config-with-templates.xml"));
    NodeList jqTemplates =
        (NodeList)(XPathFactory.newInstance().newXPath()).evaluate("/config/jq-templates/template", config, XPathConstants.NODESET);
    assertNotNull(jqTemplates);
    assertTrue(jqTemplates.getLength() > 0);
    MetricsQueryTemplate coreQueryTemplate = MetricsConfiguration.loadJqTemplates(jqTemplates).get("core-query");
    assertNotNull(coreQueryTemplate);

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode parsedMetrics = objectMapper.readTree(SolrTestCaseJ4.getFile("query-metrics.json"));
    final String[] queryMetrics = new String[]{
        "$jq:core-query(1minRate, select(.key | endswith(\".distrib.requestTimes\")), 1minRate)",
        "$jq:core-query(p75_ms, select(.key | endswith(\".distrib.requestTimes\")), p75_ms)",
        "$jq:core-query(mean_rate, select(.key | endswith(\".distrib.requestTimes\")), meanRate)",
        "$jq:core-query(local_5minRate, select(.key | endswith(\".local.requestTimes\")), 5minRate)",
        "$jq:core-query(local_median_ms, select(.key | endswith(\".local.requestTimes\")), median_ms)",
        "$jq:core-query(local_p95_ms, select(.key | endswith(\".local.requestTimes\")), p95_ms)",
        "$jq:core-query(local_count, select(.key | endswith(\".local.requestTimes\")), count, COUNTER)"
    };

    final double[] expectedMetrics = new double[]{
        5.156897804421665,
        1.31788,
        0.0031956674240800156,
        0.030666407244305586,
        0.079579,
        0.105268,
        4712
    };

    for (int m = 0; m < queryMetrics.length; m++) {
      Optional<Matcher> maybe = MetricsQueryTemplate.matches(queryMetrics[m]);
      assertTrue(maybe.isPresent());
      Matcher matcher = maybe.get();
      JsonQuery jsonQuery = JsonQuery.compile(coreQueryTemplate.applyTemplate(matcher));
      List<JsonNode> results = jsonQuery.apply(parsedMetrics);
      assertNotNull(results);
      assertTrue(results.size() == 1);
      double value = results.get(0).get("value").doubleValue();
      assertEquals(expectedMetrics[m], value, 0.0001);
    }
  }
}
