package com.timgroup.tucker.info.component;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.timgroup.tucker.info.Component;
import com.timgroup.tucker.info.Report;
import com.timgroup.tucker.info.Status;

/**
 * Reports whether the application can connect to the database.
 */
public final class DatabaseConnectionComponent extends Component {
    private final ConnectionProvider connectionProvider;
    private final boolean fetchMetadata;
    private final Status failureStatus;

    public interface ConnectionProvider {
        Connection getConnection() throws SQLException;
    }

    public DatabaseConnectionComponent(String id, String label, ConnectionProvider connectionProvider) {
        this(id, label, connectionProvider, true);
    }

    public DatabaseConnectionComponent(String id, String label, ConnectionProvider connectionProvider, boolean fetchMetadata) {
        super(id, label);
        this.connectionProvider = connectionProvider;
        this.fetchMetadata = fetchMetadata;
        this.failureStatus = Status.CRITICAL;
    }

    @Override
    public Report getReport() {
        try (Connection dbConnection = connectionProvider.getConnection()) {
            String durationString;
            long before = System.currentTimeMillis();
            try (Statement statement = dbConnection.createStatement()) {
                try (ResultSet resultSet = statement.executeQuery("select 1;")) {
                    long after = System.currentTimeMillis();
                    durationString = (after - before) + "ms";
                }
            }

            if (fetchMetadata) {
                DatabaseMetaData metaData = dbConnection.getMetaData();
                String user = metaData.getUserName();
                String jdbcUrl = metaData.getURL();
                String prefix = user != null && !user.isEmpty() ? user + " @ " + jdbcUrl : jdbcUrl;
                return new Report(Status.OK, prefix + ": " + durationString);
            }
            else {
                return new Report(Status.OK, durationString);
            }
        } catch (SQLException e) {
            return new Report(failureStatus, e.getMessage());
        }
    }
}

@@ -1441,19 +1441,17 @@
 tement()
-) %7B
+;
 %0A       
@@ -1459,21 +1459,17 @@
         
-try (
+ 
 ResultSe
@@ -1474,17 +1474,15 @@
 Set 
-resultSet
+ignored
  = s
@@ -1531,28 +1531,24 @@
             
-   
- 
 long after =
@@ -1568,36 +1568,32 @@
 ntTimeMillis();%0A
-    
                 
@@ -1638,26 +1638,8 @@
 s%22;%0A
-                %7D%0A
     

Combine try-with-resources blocks