package processes;

import interface_objects.DatabaseHandler;
import managers.Logger;
import objects.DatabaseQuery;

import java.net.URI;
import java.net.URISyntaxException;
import java.sql.*;
import java.util.HashMap;

public class DatabaseClient {
    /**
     * entry point of the database client process
     * @param args
     */
    @SuppressWarnings("InfiniteLoopStatement")
    public static void main(String[] args) {
        DatabaseQuery query;
        while (true) {
            // get a query
            query = null;
            Logger.log("DatabaseClient", "waiting for query");
            while (query == null)
                query = DatabaseHandler.receiveQuery();

            Logger.log("DatabaseClient", "got query " + query.query);
            ResultSet rs = executeQuery(query);
            Logger.log("DatabaseClient", "query " + query.query + " got " + rs);
            DatabaseHandler.addResponse(query.id, rs);
        }
    }

    /**
     * executed the given {@code dbQuery}
     * @param dbQuery the query to execute
     * @return
     * <p>
     * {@link ResultSet} if query is a select, null otherwise.
     * </p>
     * <p>
     * will not return the error if one occurred,
     * to check for errors check the {@code dbQuery} field {@link DatabaseQuery#error}
     * </p>
     */
    public static ResultSet executeQuery(DatabaseQuery dbQuery) {
        ResultSet rs = null;

        Connection connection = null;
        try {
            connection = getConnection();
            Statement stmt = connection.createStatement();
            if (dbQuery.query.startsWith("SELECT"))
                rs = stmt.executeQuery(dbQuery.query);
            else
                stmt.executeUpdate(dbQuery.query);
        }
        catch (Exception e) {
            dbQuery.error = e.getMessage();
        }
        finally {
            if (connection != null) {
                try {
                    connection.close();
                }
                catch (SQLException e) {
                    if (dbQuery.error == null)
                        dbQuery.error = "";
                    else
                        dbQuery.error += "\n";

                    dbQuery.error += e.getMessage();
                }
            }
        }

        return rs;
    }

    /**
     * gets a database connection
     * @return a database connection
     * @throws URISyntaxException syntax exception
     * @throws SQLException sql exception
     */
    private static Connection getConnection() throws URISyntaxException, SQLException {
        // local testing
        String testUri = "postgres://gstsirazztbdli:2d4c2b57af25918d67127e906604aca03aa45dbfb05b01c5617a97107a9ac1e2@ec2-54-217-235-11.eu-west-1.compute.amazonaws.com:5432/d96llmqknu88a";
        URI dbUri = new URI(testUri);
        // production
        //URI dbUri = new URI(System.getenv("DATABASE_URL"));

        int port = dbUri.getPort();
        String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ":" + port + dbUri.getPath();
        // local testing
        dbUrl += "?sslmode=require";
        Logger.log("DatabaseClient.getConnection", "database URL = " + dbUrl);

        if (dbUri.getUserInfo() != null) {
            String username = dbUri.getUserInfo().split(":")[0];
            String password = dbUri.getUserInfo().split(":")[1];
            return DriverManager.getConnection(dbUrl, username, password);
        } else {
            return DriverManager.getConnection(dbUrl);
        }
    }


    /*
    try {
                connection = getConnection();

                Statement stmt = connection.createStatement();
                stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ticks (tick timestamp)");
                stmt.executeUpdate("INSERT INTO ticks VALUES (now())");
                ResultSet rs = stmt.executeQuery("SELECT tick FROM ticks");

                ArrayList<String> output = new ArrayList<String>();
                while (rs.next()) {
                    output.add( "Read from DB: " + rs.getTimestamp("tick"));
                }

                attributes.put("results", output);
                return new ModelAndView(attributes, "db.ftl");
            } catch (Exception e) {
                attributes.put("message", "There was an error: " + e);
                return new ModelAndView(attributes, "error.ftl");
            } finally {
                if (connection != null) try{connection.close();} catch(SQLException e){}
            }

     */
}

@@ -2590,24 +2590,26 @@
 ing%0A        
+//
 String testU
@@ -2784,16 +2784,18 @@
         
+//
 URI dbUr
@@ -2838,34 +2838,32 @@
 duction%0A        
-//
 URI dbUri = new 

change production database url to the correct one