/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License;
 * you may not use this file except in compliance with the Elastic License.
 */

package org.elasticsearch.xpack.sql.jdbc;

import org.elasticsearch.Version;
import org.elasticsearch.action.main.MainResponse;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.xpack.sql.client.ClientVersion;

import java.io.IOException;
import java.sql.SQLException;

/**
 * Test class for JDBC-ES server versions checks.
 * 
 * It's using a {@code MockWebServer} to be able to create a response just like the one an ES instance
 * would create for a request to "/", where the ES version used is configurable. 
 */
public class VersionParityTests extends WebServerTestCase {

    public void testExceptionThrownOnIncompatibleVersions() throws IOException, SQLException {
        Version version = VersionUtils.randomVersionBetween(random(), null, VersionUtils.getPreviousVersion(Version.V_7_7_0));
        logger.info("Checking exception is thrown for version {}", version);
        prepareResponse(version);
        
        String url = JdbcConfiguration.URL_PREFIX + webServerAddress();
        SQLException ex = expectThrows(SQLException.class, () -> new JdbcHttpClient(JdbcConfiguration.create(url, null, 0)));
        assertEquals("This version of the JDBC driver is only compatible with Elasticsearch version " +
            ClientVersion.CURRENT.majorMinorToString() + " or newer; attempting to connect to a server " +
            "version " + version.toString(), ex.getMessage());
    }
    
    public void testNoExceptionThrownForCompatibleVersions() throws IOException {
        String url = JdbcConfiguration.URL_PREFIX + webServerAddress();
        Version version = Version.CURRENT;
        try {
            do {
                prepareResponse(version);
                new JdbcHttpClient(JdbcConfiguration.create(url, null, 0));
                version = VersionUtils.getPreviousVersion(version);
            } while (version.compareTo(Version.V_7_7_0) >= 0);
        } catch (SQLException sqle) {
            fail("JDBC driver version and Elasticsearch server version should be compatible. Error: " + sqle);
        }
    }
    
    void prepareResponse(Version version) throws IOException {
        MainResponse response = version == null ? createCurrentVersionMainResponse() : createMainResponse(version);        
        webServer().enqueue(new MockResponse().setResponseCode(200).addHeader("Content-Type", "application/json").setBody(
                XContentHelper.toXContent(response, XContentType.JSON, false).utf8ToString()));
    }
}

@@ -625,16 +625,69 @@
 Version;
+%0Aimport org.elasticsearch.xpack.sql.proto.SqlVersion;
 %0A%0Aimport
@@ -1134,32 +1134,104 @@
  SQLException %7B%0A
+        String url = JdbcConfiguration.URL_PREFIX + webServerAddress();%0A
         Version 
@@ -1222,33 +1222,38 @@
         Version 
-v
+firstV
 ersion = Version
@@ -1262,44 +1262,104 @@
 ils.
-randomVersionBetween(random(), null,
+getFirstVersion();%0A        Version version = Version.V_7_7_0;%0A        do %7B%0A            version =
  Ver
@@ -1391,27 +1391,22 @@
 ion(
-V
+v
 ersion
-.V_7_7_0));%0A
+);%0A    
     
@@ -1470,32 +1470,37 @@
  %7B%7D%22, version);%0A
+%0A    
         prepareR
@@ -1529,89 +1529,235 @@
     
-%0A
     
-    String url = JdbcConfiguration.URL_PREFIX + webServerAddress
+// Client's version is wired up to patch level, excluding the qualifier =%3E generate the test version as the server does it.%0A            String versionString = SqlVersion.fromString(version.toString()).toString
 ();%0A
+%0A 
         
 SQLE
@@ -1752,16 +1752,19 @@
         
+   
 SQLExcep
@@ -1881,16 +1881,20 @@
         
+    
 assertEq
@@ -1993,16 +1993,20 @@
         
+ 
+   
 ClientVe
@@ -2088,24 +2088,28 @@
  server %22 +%0A
+    
             
@@ -2128,27 +2128,22 @@
  version
-.to
 String
-()
 , ex.get
@@ -2150,24 +2150,79 @@
 Message());%0A
+        %7D while (version.compareTo(firstVersion) %3E 0);%0A
     %7D%0A    %0A 

Fix test on incompatible client versions (#56234)