package org.umlg.sqlg.test.tp3;

import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
import org.apache.tinkerpop.gremlin.LoadGraphWith;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.umlg.sqlg.sql.dialect.SqlDialect;
import org.umlg.sqlg.structure.*;

import java.beans.PropertyVetoException;
import java.lang.reflect.Constructor;
import java.sql.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Date: 2014/07/13
 * Time: 5:57 PM
 */
public class SqlgPostgresProvider extends AbstractGraphProvider {

    private static final Set<Class> IMPLEMENTATIONS = new HashSet<Class>() {{
        add(SqlgEdge.class);
        add(SqlgElement.class);
        add(SqlgGraph.class);
        add(SqlgProperty.class);
        add(SqlgVertex.class);
        add(SqlgVertexProperty.class);
        add(DefaultGraphTraversal.class);
    }};

    @Override
    public Map<String, Object> getBaseConfiguration(String graphName, Class<?> test, String testMethodName, LoadGraphWith.GraphData loadGraphWith) {
        return new HashMap<String, Object>() {{
            put("gremlin.graph", SqlgGraph.class.getName());
            put("jdbc.url", "jdbc:postgresql://localhost:5432/" + graphName);
            put("jdbc.username", "postgres");
            put("jdbc.password", "postgres");
        }};
    }

    @Override
    public void clear(final Graph g, final Configuration configuration) throws Exception {
        SqlgDataSource sqlgDataSource = null;
        if (null != g) {
            if (g.features().graph().supportsTransactions() && g.tx().isOpen())
                g.tx().rollback();
            g.close();
        }
        SqlDialect sqlDialect;
        try {
            Class<?> sqlDialectClass = Class.forName("org.umlg.sqlg.sql.dialect.PostgresDialect");
            Constructor<?> constructor = sqlDialectClass.getConstructor(Configuration.class);
            sqlDialect = (SqlDialect) constructor.newInstance(configuration);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        try {
            sqlgDataSource = SqlgDataSource.setupDataSource(
                    sqlDialect.getJdbcDriver(),
                    configuration);
            try (Connection conn = sqlgDataSource.get(configuration.getString("jdbc.url")).getConnection()) {
                DatabaseMetaData metadata = conn.getMetaData();
                if (sqlDialect.supportsCascade()) {
                    String catalog = null;
                    String schemaPattern = null;
                    String tableNamePattern = "%";
                    String[] types = {"TABLE"};
                    ResultSet result = metadata.getTables(catalog, schemaPattern, tableNamePattern, types);
                    while (result.next()) {
                        StringBuilder sql = new StringBuilder("DROP TABLE ");
                        sql.append(sqlDialect.maybeWrapInQoutes(result.getString(3)));
                        sql.append(" CASCADE");
                        if (sqlDialect.needsSemicolon()) {
                            sql.append(";");
                        }
                        try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
                            preparedStatement.executeUpdate();
                        }
                    }
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e);
        } finally {
            if (sqlgDataSource != null)
                sqlgDataSource.close(configuration.getString("jdbc.url"));
        }
    }

    @Override
    public Set<Class> getImplementations() {
        return IMPLEMENTATIONS;
    }

    @Override
    public Object convertId(final Object id, final Class<? extends Element> c) {
        return "jippo.jippo" + SchemaManager.LABEL_SEPARATOR + id.toString();
    }
}

@@ -1530,32 +1530,68 @@
 %22, %22postgres%22);%0A
+            put(%22maxPoolSize%22, 10);%0A
         %7D%7D;%0A    

add maxPoolSetting for travis