package io.digdag.standards.operator.jdbc;

import java.util.Properties;
import java.time.Duration;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.DriverManager;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import io.digdag.client.config.Config;
import io.digdag.spi.SecretProvider;
import io.digdag.util.DurationParam;
import static java.util.Locale.ENGLISH;

public abstract class AbstractJdbcConnectionConfig
{
    protected static Optional<String> getPassword(SecretProvider secrets, Config params)
    {
        Optional<String> passwordOverrideKey = params.getOptional("password_override", String.class);

        Optional<String> overriddenPassword = Optional.absent();
        if (passwordOverrideKey.isPresent()) {
            overriddenPassword = secrets.getSecretOptional(passwordOverrideKey.get());
        }

        return overriddenPassword.or(secrets.getSecretOptional("password"));
    }

    public abstract String host();

    public abstract int port();

    public abstract boolean ssl();

    public abstract String user();

    public abstract Optional<String> password();

    public abstract String database();

    public abstract DurationParam connectTimeout();

    public abstract DurationParam socketTimeout();

    public abstract String jdbcProtocolName();

    public abstract String jdbcDriverName();

    public abstract Properties buildProperties();

    public String url()
    {
        return String.format(ENGLISH, "jdbc:%s://%s:%d/%s", jdbcProtocolName(), host(), port(), database());
    }

    public Connection openConnection()
    {
        try {
            Class.forName(jdbcDriverName());
        }
        catch (ClassNotFoundException e) {
            throw Throwables.propagate(e);
        }

        try {
            return DriverManager.getConnection(url(), buildProperties());
        }
        catch (SQLException ex) {
            throw new DatabaseException("Failed to connect to the database", ex);
        }
    }
}

@@ -668,25 +668,24 @@
 class);%0A
-%0A
         
 Optional
@@ -680,64 +680,46 @@
     
-Optional%3CString%3E overriddenPassword = Optional.ab
+if (passwordOverrideKey.isPre
 sent()
-;
+) %7B
 %0A   
@@ -719,36 +719,45 @@
 ) %7B%0A        
-if (
+    // When %60
 password
 OverrideKey.
@@ -748,68 +748,87 @@
 word
-O
+_o
 verride
-Key.isPresent()) %7B%0A            overriddenPassword = 
+%60 is specified, the key needs to exist%0A            return Optional.of(
 secr
@@ -840,24 +840,16 @@
 etSecret
-Optional
 (passwor
@@ -867,16 +867,17 @@
 y.get())
+)
 ;%0A      
@@ -884,46 +884,42 @@
   %7D%0A
-%0A        return overriddenPassword.or(
+        else %7B%0A            return 
 secr
@@ -951,18 +951,27 @@
 ssword%22)
-)
 ;
+%0A        %7D
 %0A    %7D%0A%0A

Validate that when `pg.password_override` is set, the key should exist