/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.shardingsphere.infra.database.metadata.url;

import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;

import java.util.Map.Entry;
import java.util.Properties;

/**
 * JDBC URL appender.
 */
public final class JdbcUrlAppender {
    
    /**
     * Append query properties.
     *
     * @param jdbcURL JDBC URL to be appended
     * @param queryProps query properties to be appended
     * @return appended JDBC URL
     */
    public String appendQueryProperties(final String jdbcURL, final Properties queryProps) {
        Properties currentQueryProps = DatabaseTypeRegistry.getDatabaseTypeByURL(jdbcURL).getDataSourceMetaData(jdbcURL, null).getQueryProperties();
        if (hasConflictedQueryProperties(currentQueryProps, queryProps)) {
            Properties mergedQueryProps = new Properties();
            mergedQueryProps.putAll(currentQueryProps);
            mergedQueryProps.putAll(queryProps);
            return appendQueryPropertiesOnURLBuilder(jdbcURL.substring(0, jdbcURL.indexOf('?') + 1), mergedQueryProps);
        }
        return appendQueryPropertiesOnURLBuilder(jdbcURL + (currentQueryProps.isEmpty() ? "?" : "&"), queryProps);
    }
    
    private boolean hasConflictedQueryProperties(final Properties currentQueryProps, final Properties tobeAppendedQueryProps) {
        return tobeAppendedQueryProps.keySet().stream().anyMatch(currentQueryProps::containsKey);
    }
    
    private String appendQueryPropertiesOnURLBuilder(final String jdbcUrlPrefix, final Properties queryProps) {
        StringBuilder result = new StringBuilder(jdbcUrlPrefix);
        for (Entry<Object, Object> entry : queryProps.entrySet()) {
            result.append(entry.getKey());
            if (null != entry.getValue()) {
                result.append("=").append(entry.getValue());
            }
            result.append("&");
        }
        result.deleteCharAt(result.length() - 1);
        return result.toString();
    }
}

@@ -1132,18 +1132,18 @@
 am jdbcU
-RL
+rl
  JDBC UR
@@ -1315,18 +1315,18 @@
 ng jdbcU
-RL
+rl
 , final 
@@ -1436,18 +1436,18 @@
 RL(jdbcU
-RL
+rl
 ).getDat
@@ -1467,18 +1467,18 @@
 ta(jdbcU
-RL
+rl
 , null).
@@ -1507,20 +1507,23 @@
         
-if (
+return 
 hasConfl
@@ -1573,19 +1573,16 @@
 ryProps)
-) %7B
 %0A       
@@ -1590,221 +1590,28 @@
     
-Properties mergedQueryProps = new Properties();%0A            mergedQueryProps.putAll(currentQueryProps);%0A            mergedQueryProps.putAll(queryProps);%0A            return appendQueryPropertiesOnURLBuilder
+    ? concat
 (jdbcU
-RL
+rl
 .sub
@@ -1625,18 +1625,18 @@
 0, jdbcU
-RL
+rl
 .indexOf
@@ -1651,26 +1651,59 @@
 1), 
-m
+getM
 erged
-QueryProps);
+Properties(currentQueryProps, queryProps))
 %0A   
@@ -1707,26 +1707,24 @@
         
-%7D%0A
         
 return a
@@ -1719,56 +1719,24 @@
     
-return appendQueryPropertiesOnURLBuilder
+: concat
 (jdbcU
-RL
+rl
  + (
@@ -1905,17 +1905,17 @@
 rties to
-b
+B
 eAppende
@@ -1946,17 +1946,17 @@
 eturn to
-b
+B
 eAppende
@@ -2050,29 +2050,112 @@
 private 
-String a
+Properties getMergedProperties(final Properties currentQueryProps, final Properties toBeA
 ppend
+ed
 QueryPro
@@ -2159,26 +2159,207 @@
 Prop
-ertiesOnURLBuilder
+s) %7B%0A        Properties result = new Properties();%0A        result.putAll(currentQueryProps);%0A        result.putAll(toBeAppendedQueryProps);%0A        return result;%0A    %7D%0A    %0A    private String concat
 (fin
@@ -2375,22 +2375,16 @@
  jdbcUrl
-Prefix
 , final 
@@ -2468,14 +2468,8 @@
 cUrl
-Prefix
 );%0A 

Refactor JdbcUrlAppender (#14674)