package com.linkedin.gms.factory.common;

import java.util.concurrent.TimeUnit;

import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Config;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Neo4jDriverFactory {
  @Value("${NEO4J_USERNAME:neo4j}")
  private String username;

  @Value("${NEO4J_PASSWORD:datahub}")
  private String password;

  @Value("${NEO4J_URI:bolt://localhost}")
  private String uri;

  @Value("${NEO4J_MAX_CONNECTION_POOL_SIZE:100}")
  private Integer neo4jMaxConnectionPoolSize;

  @Value("${NEO4J_MAX_CONNECTION_ACQUISITION_TIMEOUT_IN_SECONDS:60}")
  private Long neo4jMaxConnectionAcquisitionTimeout;

  @Value("${NEO4j_MAX_CONNECTION_LIFETIME_IN_HOURS:1}")
  private Long neo4jMaxConnectionLifetime;

  @Value("${NEO4J_MAX_TRANSACTION_RETRY_TIME_IN_SECONDS:30}")
  private Long neo4jMaxTransactionRetryTime;

  @Bean(name = "neo4jDriver")
  protected Driver createInstance() {
    Config.ConfigBuilder builder = Config.builder();
    builder.withMaxConnectionPoolSize(neo4jMaxConnectionPoolSize);
    builder.withConnectionAcquisitionTimeout(neo4jMaxConnectionAcquisitionTimeout, TimeUnit.SECONDS);
    builder.withMaxConnectionLifetime(neo4jMaxConnectionLifetime, TimeUnit.HOURS);
    builder.withMaxTransactionRetryTime(neo4jMaxTransactionRetryTime, TimeUnit.SECONDS);

    return GraphDatabase.driver(uri, AuthTokens.basic(username, password), builder.build());
  }
}

@@ -857,58 +857,276 @@
 %0A%0A  
-@Value(%22$%7BNEO4j_MAX_CONNECTION_LIFETIME_IN_HOURS:1
+// Kept for sake of backwards compatibility. Instead use NEO4j_MAX_CONNECTION_LIFETIME_IN_SECONDS%0A  @Value(%22$%7BNEO4j_MAX_CONNECTION_LIFETIME_IN_HOURS:#%7Bnull%7D%7D%22)%0A  private Long neo4jMaxConnectionLifetimeInHours;%0A%0A  @Value(%22$%7BNEO4j_MAX_CONNECTION_LIFETIME_IN_SECONDS:3600
 %7D%22)%0A
@@ -1166,16 +1166,25 @@
 Lifetime
+InSeconds
 ;%0A%0A  @Va
@@ -1286,16 +1286,138 @@
 yTime;%0A%0A
+  @Value(%22$%7BNEO4J_CONNECTION_LIVENESS_CHECK_TIMEOUT_IN_SECONDS:-1%7D%22)%0A  private Long neo4jConnectionLivenessCheckTimeout;%0A%0A
   @Bean(
@@ -1476,16 +1476,17 @@
 nce() %7B%0A
+%0A
     Conf
@@ -1763,16 +1763,18 @@
 Lifetime
+()
 , TimeUn
@@ -1776,20 +1776,22 @@
 imeUnit.
-HOUR
+SECOND
 S);%0A    
@@ -1879,100 +1879,514 @@
 S);%0A
-%0A    return GraphDatabase.driver(uri, AuthTokens.basic(username, password), builder.build())
+    builder.withConnectionLivenessCheckTimeout(neo4jConnectionLivenessCheckTimeout, TimeUnit.SECONDS);%0A%0A    return GraphDatabase.driver(uri, AuthTokens.basic(username, password), builder.build());%0A  %7D%0A%0A  private Long neo4jMaxConnectionLifetime() %7B%0A%0A    // neo4jMaxConnectionLifetimeInHours has precedence over neo4jMaxConnectionLifetimeInSeconds%0A    if (neo4jMaxConnectionLifetimeInHours != null) %7B%0A      return neo4jMaxConnectionLifetimeInHours * 3600;%0A    %7D%0A    return neo4jMaxConnectionLifetimeInSeconds
 ;%0A  

Fix 2592 neo4j connection options (#2632)