// Copyright 2017 The Promagent Authors
//
// Licensed 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 io.promagent.it;

import com.squareup.okhttp.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class SpringIT {

    /**
     * Run some HTTP queries against a Docker container from image promagent/spring-promagent.
     * <p/>
     * The Docker container is started by the maven-docker-plugin when running <tt>mvn verify -Pspring</tt>.
     */
    @Test
    public void testSpring() throws Exception {
        OkHttpClient client = new OkHttpClient();
        Request metricsRequest = new Request.Builder().url(System.getProperty("promagent.url") + "/metrics").build();

        // Execute two POST requests
        Response restResponse = client.newCall(makePostRequest("Frodo", "Baggins")).execute();
        assertEquals(201, restResponse.code());
        restResponse = client.newCall(makePostRequest("Bilbo", "Baggins")).execute();
        assertEquals(201, restResponse.code());

        // Query Prometheus metrics from promagent
        Response metricsResponse = client.newCall(metricsRequest).execute();
        String[] metricsLines = metricsResponse.body().string().split("\n");

        String httpRequestsTotal = Arrays.stream(metricsLines)
                .filter(m -> m.contains("http_requests_total"))
                .filter(m -> m.contains("method=\"POST\""))
                .filter(m -> m.contains("path=\"/people\""))
                .filter(m -> m.contains("status=\"201\""))
                .findFirst().orElseThrow(() -> new Exception("http_requests_total metric not found."));

        assertTrue(httpRequestsTotal.endsWith("2.0"), "Value should be 2.0 for " + httpRequestsTotal);

        String sqlQueriesTotal = Arrays.stream(metricsLines)
                .filter(m -> m.contains("sql_queries_total"))
                .filter(m -> m.contains("query=\"insert into person (id, first_name, last_name) values (...)\""))
                .filter(m -> m.contains("method=\"POST\""))
                .filter(m -> m.contains("path=\"/people\""))
                .findFirst().orElseThrow(() -> new Exception("sql_queries_total metric not found."));

        assertTrue(sqlQueriesTotal.endsWith("2.0"), "Value should be 2.0 for " + sqlQueriesTotal);
    }

    private Request makePostRequest(String firstName, String lastName) {
        return new Request.Builder()
                .url(System.getProperty("deployment.url") + "/people")
                .method("POST", RequestBody.create(
                        MediaType.parse("application/json"),
                        "{  \"firstName\" : \"" + firstName + "\",  \"lastName\" : \"" + lastName + "\" }"))
                .build();
    }
}

@@ -2591,33 +2591,257 @@
     
-.filter(m -%3E m.contain
+// The following regular expression tests for this string, but allows the parameters 'id', 'fist_name', 'last_name' to change order:%0A                // query=%22insert into person (first_name, last_name, id)%22%0A                .filter(m -%3E m.matche
 s(%22
+.*
 quer
@@ -2867,13 +2867,24 @@
 son 
-(id, 
+%5C%5C((?=.*id)(?=.*
 firs
@@ -2881,34 +2881,38 @@
 )(?=.*first_name
-, 
+)(?=.*
 last_name) value
@@ -2909,16 +2909,21 @@
 ame)
+.*%5C%5C)
  values 
 (...
@@ -2922,15 +2922,21 @@
 ues 
+%5C%5C
 (...
+%5C%5C
 )%5C%22
+.*
 %22))%0A

fix failing test