/*
 * 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.prestosql.server.rpm;

import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

import static java.lang.String.format;
import static java.sql.DriverManager.getConnection;
import static java.util.Arrays.asList;
import static org.testcontainers.containers.wait.strategy.Wait.forLogMessage;
import static org.testng.Assert.assertEquals;

public class ServerIT
{
    @Parameters("rpm")
    @Test
    public void testWithJava8(String rpm)
            throws Exception
    {
        testServer("prestodev/centos7-oj8", rpm);
    }

    @Parameters("rpm")
    @Test
    public void testWithJava11(String rpm)
            throws Exception
    {
        testServer("prestodev/centos7-oj11", rpm);
    }

    private static void testServer(String baseImage, String rpmHostPath)
            throws Exception
    {
        String rpm = "/" + new File(rpmHostPath).getName();

        String command = "" +
                // install RPM
                "yum localinstall -q -y " + rpm + "\n" +
                // create Hive catalog file
                "mkdir /etc/presto/catalog\n" +
                "cat > /etc/presto/catalog/hive.properties <<\"EOT\"\n" +
                "connector.name=hive-hadoop2\n" +
                "hive.metastore.uri=thrift://localhost:9083\n" +
                "EOT\n" +
                // start server
                "/etc/init.d/presto start\n" +
                // allow tail to work with Docker's non-local file system
                "tail ---disable-inotify -F /var/log/presto/server.log\n";

        try (GenericContainer<?> container = new GenericContainer<>(baseImage)) {
            container.withExposedPorts(8080)
                    .withFileSystemBind(rpmHostPath, rpm, BindMode.READ_ONLY)
                    .withCommand("sh", "-xeuc", command)
                    .waitingFor(forLogMessage(".*SERVER STARTED.*", 1).withStartupTimeout(Duration.ofMinutes(5)))
                    .start();

            assertServer(container.getContainerIpAddress(), container.getMappedPort(8080));
        }
    }

    private static void assertServer(String host, int port)
            throws SQLException
    {
        String url = format("jdbc:presto://%s:%s", host, port);
        try (Connection connection = getConnection(url, "test", null);
                Statement statement = connection.createStatement();
                ResultSet rs = statement.executeQuery("SHOW CATALOGS")) {
            Set<String> catalogs = new HashSet<>();
            while (rs.next()) {
                catalogs.add(rs.getString(1));
            }
            assertEquals(catalogs, new HashSet<>(asList("system", "hive")));
        }
    }
}

@@ -1233,16 +1233,134 @@
 Equals;%0A
+import static org.testng.Assert.assertFalse;%0Aimport static org.testng.Assert.assertTrue;%0A%0A@Test(singleThreaded = true)
 %0Apublic 
@@ -1529,24 +1529,31 @@
 s7-oj8%22, rpm
+, %221.8%22
 );%0A    %7D%0A%0A  
@@ -1709,16 +1709,22 @@
 11%22, rpm
+, %2211%22
 );%0A    %7D
@@ -1796,16 +1796,44 @@
 HostPath
+, String expectedJavaVersion
 )%0A      
@@ -2343,24 +2343,207 @@
   %22EOT%5Cn%22 +%0A
+                // create JMX catalog file%0A                %22cat %3E /etc/presto/catalog/jmx.properties %3C%3C%5C%22EOT%5C%22%5Cn%22 +%0A                %22connector.name=jmx%5Cn%22 +%0A                %22EOT%5Cn%22 +%0A
             
@@ -3255,16 +3255,37 @@
 rt(8080)
+, expectedJavaVersion
 );%0A     
@@ -3354,16 +3354,44 @@
 int port
+, String expectedJavaVersion
 )%0A      
@@ -3623,21 +3623,20 @@
 tement()
-;%0A   
+) %7B%0A
         
@@ -3639,17 +3639,21 @@
         
- 
+try (
 ResultSe
@@ -3655,17 +3655,24 @@
 ultSet r
-s
+esultSet
  = state
@@ -3705,24 +3705,28 @@
 TALOGS%22)) %7B%0A
+    
             
@@ -3781,16 +3781,20 @@
     
+    
 while (r
 s.ne
@@ -3789,17 +3789,24 @@
 while (r
-s
+esultSet
 .next())
@@ -3804,24 +3804,28 @@
 t.next()) %7B%0A
+    
             
@@ -3842,17 +3842,24 @@
 gs.add(r
-s
+esultSet
 .getStri
@@ -3874,26 +3874,34 @@
             
+  
-%7D%0A
+  %7D%0A    
             
@@ -3964,12 +3964,415 @@
 ive%22
-)));
+, %22jmx%22)));%0A            %7D%0A            try (ResultSet resultSet = statement.executeQuery(%22SELECT specversion FROM jmx.current.%5C%22java.lang:type=runtime%5C%22%22)) %7B%0A                assertTrue(resultSet.next(), %22No data was returned%22);%0A                assertEquals(resultSet.getString(1), expectedJavaVersion);%0A                assertFalse(resultSet.next(), %22Expected single row output, but got more.%22);%0A            %7D
 %0A   

Verify java version during RPM tests