package io.quantumdb.driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Properties;
import java.util.logging.Logger;

public class Driver implements java.sql.Driver {

	static {
		try {
			java.sql.DriverManager.registerDriver(new Driver());
		}
		catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private java.sql.Driver delegate;
	private Transformer transformer;

	private Driver() {
		// Prevent others from instantiating this class.
	}

	@Override
	public Connection connect(String url, Properties info) throws SQLException {
		if (!url.startsWith("jdbc:quantumdb:")) {
			return null;
		}
		url = url.substring(0, 4) + ":" + url.substring(15, url.length());

		try {
			Class.forName("org.postgresql.Driver");
		}
		catch (ClassNotFoundException e) {
			throw new SQLException("Could not locate delegate driver.", e);
		}

		String version = parseVersion(url);
		this.delegate = DriverManager.getDriver(url);
		Connection connection = delegate.connect(url, info);
		QueryRewriter queryRewriter = new PostgresqlQueryRewriter(true);
		this.transformer = new Transformer(connection, queryRewriter, version);

		return new ProxyConnection(connection, transformer);
	}

	@Override
	public boolean acceptsURL(String url) throws SQLException {
		return url != null && url.startsWith("jdbc:quantumdb:");
	}

	@Override
	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
		return delegate.getPropertyInfo(url, info);
	}

	@Override
	public int getMajorVersion() {
		return delegate.getMajorVersion();
	}

	@Override
	public int getMinorVersion() {
		return delegate.getMinorVersion();
	}

	@Override
	public boolean jdbcCompliant() {
		return delegate.jdbcCompliant();
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		return delegate.getParentLogger();
	}

	public String getTableId(String tableName) {
		return transformer.getTableId(tableName);
	}

	private String parseVersion(String url) {
		String[] lookups = new String[] { "?version=", "&version=" };

		int index = -1;
		for (String lookup : lookups) {
			index = url.indexOf(lookup);
			if (index > -1) {
				index += lookup.length();
				break;
			}
		}

		if (index == -1) {
			return null;
		}

		String chunk = url.substring(index);
		int end = chunk.indexOf("&");
		if (end == -1) {
			end = chunk.length();
		}

		return chunk.substring(0, end);
	}

}

@@ -1017,16 +1017,324 @@
 n(url);%0A
+%09%09if (version != null) %7B%0A%09%09%09String applicationName = info.getProperty(%22ApplicationName%22);%0A%09%09%09if (applicationName != null && !applicationName.equals(%22%22)) %7B%0A%09%09%09%09applicationName += %22 - %22 + version;%0A%09%09%09%7D%0A%09%09%09else %7B%0A%09%09%09%09applicationName = version;%0A%09%09%09%7D%0A%09%09%09info.setProperty(%22ApplicationName%22, applicationName);%0A%09%09%7D%0A%0A
 %09%09this.d

Store the chosen database schema version of the client in the application_name.