/**
 * Copyright 2016 Palantir Technologies
 *
 * Licensed under the BSD-3 License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * 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 com.palantir.atlasdb.keyvalue.cassandra;

import java.util.Set;
import java.util.stream.Collectors;

import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.KsDef;
import org.apache.thrift.TException;

import com.palantir.atlasdb.cassandra.CassandraKeyValueServiceConfig;
import com.palantir.atlasdb.cassandra.CassandraKeyValueServiceConfigManager;
import com.palantir.atlasdb.keyvalue.api.TableReference;
import com.palantir.atlasdb.keyvalue.impl.AbstractKeyValueService;
import com.palantir.common.base.FunctionCheckedException;
import com.palantir.common.base.Throwables;

class CassandraDao {
    private final CassandraClientPool clientPool;
    private final CassandraKeyValueServiceConfigManager configManager;

    CassandraDao(CassandraClientPool clientPool, CassandraKeyValueServiceConfigManager configManager) {
        this.clientPool = clientPool;
        this.configManager = configManager;
    }

    Set<TableReference> getExistingTables() {
        final CassandraKeyValueServiceConfig config = configManager.getConfig();
        try {
            return clientPool.runWithRetry(new FunctionCheckedException<Cassandra.Client, Set<TableReference>, Exception>() {

                @Override
                public Set<TableReference> apply(Cassandra.Client client) throws Exception {
                    return client.describe_keyspace(config.keyspace()).getCf_defs().stream().map(
                            cf -> CassandraKeyValueService.fromInternalTableName(cf.getName())).collect(Collectors.toSet());
                }

                @Override
                public String toString() {
                    return "describe_keyspace(" + config.keyspace() + ")";
                }
            });
        } catch (Exception e) {
            throw Throwables.throwUncheckedException(e);
        }
    }

    Set<TableReference> getExistingTablesLowerCased() throws TException {
        return getExistingTablesLowerCased(configManager.getConfig().keyspace());
    }

    private Set<TableReference> getExistingTablesLowerCased(String keyspace) throws TException {
        return clientPool.runWithRetry((client) -> getExistingTablesLowerCased(client, keyspace));
    }

    private Set<TableReference> getExistingTablesLowerCased(Cassandra.Client client, String keyspace) throws TException {
        KsDef ks = client.describe_keyspace(keyspace);

        return ks.getCf_defs().stream()
                .map(cf -> CassandraKeyValueService.fromInternalTableName(cf.getName().toLowerCase()))
                .collect(Collectors.toSet());
    }
}

@@ -654,16 +654,52 @@
 il.Set;%0A
+import java.util.function.Function;%0A
 import j
@@ -773,16 +773,58 @@
 sandra;%0A
+import org.apache.cassandra.thrift.CfDef;%0A
 import o
@@ -899,78 +899,8 @@
 n;%0A%0A
-import com.palantir.atlasdb.cassandra.CassandraKeyValueServiceConfig;%0A
 impo
@@ -1033,75 +1033,8 @@
 ce;%0A
-import com.palantir.atlasdb.keyvalue.impl.AbstractKeyValueService;%0A
 impo
@@ -1526,51 +1526,23 @@
     
-final CassandraKeyValueServiceConfig config
+String keyspace
  = c
@@ -1565,17 +1565,29 @@
 Config()
-;
+.keyspace();%0A
 %0A       
@@ -1636,16 +1636,37 @@
 thRetry(
+%0A                    
 new Func
@@ -1891,201 +1891,42 @@
 urn 
-client.describe_keyspace(config.keyspace()).getCf_defs().stream().map(%0A                            cf -%3E CassandraKeyValueService.fromInternalTableName(cf.getName())).collect(Collectors.toSet()
+getExistingTables(client, keyspace
 );%0A 
@@ -2066,23 +2066,16 @@
 %22 + 
-config.
 keyspace
 () +
@@ -2070,18 +2070,16 @@
 keyspace
-()
  + %22)%22;%0A
@@ -2633,26 +2633,16 @@
 ngTables
-LowerCased
 (Cassand
@@ -2666,32 +2666,485 @@
  String keyspace
+) throws TException %7B%0A        return getTableReferences(client, keyspace, CfDef::getName);%0A    %7D%0A%0A    private Set%3CTableReference%3E getExistingTablesLowerCased(Cassandra.Client client, String keyspace) throws TException %7B%0A        return getTableReferences(client, keyspace, cf -%3E cf.getName().toLowerCase());%0A    %7D%0A%0A    private Set%3CTableReference%3E getTableReferences(Cassandra.Client client, String keyspace,%0A            Function%3CCfDef, String%3E nameGetter
 ) throws TExcept
@@ -3266,22 +3266,49 @@
    .map(
-cf -%3E 
+nameGetter)%0A                .map(
 Cassandr
@@ -3323,17 +3323,18 @@
 eService
-.
+::
 fromInte
@@ -3350,36 +3350,8 @@
 Name
-(cf.getName().toLowerCase())
 )%0A  

Remove duplication from CassandraDao