package hiro.yoshioka.sdh;

import hiro.yoshioka.util.StringUtil;

public enum DatabaseType {
	// -------------------------------------------------------------------------
	// NO SQL
	// -------------------------------------------------------------------------
	EVERNOTE("evernote", "evernote"), MONGO(".*mongodb.Mongo",
			"com.mongodb.Mongo"),
	// -------------------------------------------------------------------------
	// LOTSU NOTES DOMINO SERVER
	// -------------------------------------------------------------------------
	DOMINO("lotus.domino.database", "lotus.domino.database"),
	// -------------------------------------------------------------------------
	// TWITTER
	// -------------------------------------------------------------------------
	TWITTER("twitter4j.Twitter", "twitter4j.Twitter"),
	// -------------------------------------------------------------------------
	// SQL
	// -------------------------------------------------------------------------
	/** oracle */
	ORACLE(".*oracle.*", StringUtil.EMPTY_STRING),
	/** my sql */
	MYSQL(".*mysql.*", StringUtil.EMPTY_STRING),
	/** hyper sonic sql */
	HSQL("org.hsqldb.*", "org.hsqldb.jdbcDriver"),
	/** microsoft sql server */
	MS_SQLSERVER(".*sqlserver.*", StringUtil.EMPTY_STRING),
	/** fujitsu sybase */
	SYBASE(".*sybase.*", StringUtil.EMPTY_STRING),
	/** postgres */
	POSTGRES(".*postgresql.*", StringUtil.EMPTY_STRING),
	/** sqlite */
	SQLITE(".*sqlite.*", StringUtil.EMPTY_STRING),
	/** odbc */
	ODBC(".*odbc.*", "sun.jdbc.odbc.JdbcOdbcDriver"),
	/** unkown */
	UNKNOWN("unkown", StringUtil.EMPTY_STRING);

	public static DatabaseType[] INTERNAL_JARS = { HSQL, ODBC, MONGO, TWITTER,
			EVERNOTE };

	private String driverPattern;
	private String driverName;

	private DatabaseType(String driverPattern, String driverName) {
		this.driverPattern = driverPattern;
		this.driverName = driverName;
	}

	public static DatabaseType parse(String driver) {
		for (DatabaseType types : values()) {
			if (driver.matches(types.driverPattern)) {
				return types;
			}
		}
		System.out.println("DatabaseType#parse retunKnown");
		return UNKNOWN;
	}

	public boolean forceAutoCommitTrue() {
		switch (this) {
		case SQLITE:
		case MS_SQLSERVER:
			return true;
		}
		return false;
	}

	public boolean isAutoCommitRecommended() {
		switch (this) {
		case SQLITE:
		case MS_SQLSERVER:
		case POSTGRES:
			return true;
		}
		return false;
	}

	public String getDriverName() {
		return driverName;
	}

	public String getDriverPattern() {
		return driverPattern;
	}

	public boolean isMongo() {
		return MONGO.equals(this);
	}

	public boolean isDomino() {
		return DOMINO.equals(this);
	}

	public boolean isTwitter() {
		return TWITTER.equals(this);
	}

	public boolean isOracle() {
		return ORACLE.equals(this);
	}

	public boolean isSQLServer() {
		return MS_SQLSERVER.equals(this);
	}

	public boolean isSQLite() {
		return SQLITE.equals(this);
	}

	public boolean isHsql() {
		return HSQL.equals(this);
	}

	public boolean isPostgres() {
		return POSTGRES.equals(this);
	}

	public boolean isEvernote() {
		return EVERNOTE.equals(this);
	}

	public boolean isMySQL() {
		return MYSQL.equals(this);
	}

	public boolean needsDatabaseNameDefine() {
		switch (this) {
		case MONGO:
			return true;
		}
		return false;
	}

	public boolean enableRecursiveSearch() {
		switch (this) {
		case MONGO:
		case DOMINO:
			return true;
		}
		return false;
	}

	public boolean enableKeepAlive() {
		return !StringUtil.isEmpty(getKeepAliveStatement());
	}

	public boolean enableCategoryFilter() {
		switch (this) {
		case DOMINO:
		case ORACLE:
			return true;
		}
		return false;
	}

	public boolean enableNsaFilePathFilter() {
		switch (this) {
		case DOMINO:
			return true;
		}
		return false;
	}

	public boolean supportVarchar2() {
		switch (this) {
		case ORACLE:
			return true;
		}
		return false;
	}

	public boolean isInternalJar() {
		for (DatabaseType type : INTERNAL_JARS) {
			if (type.equals(this)) {
				return true;
			}
		}
		return false;
	}

	public String getKeepAliveStatement() {
		switch (this) {
		case MYSQL:
			return "select sysdate() from dual;";
		case ORACLE:
			return "SELECT SYSDATE FROM DUAL";
		case POSTGRES:
			return "SELECT CURRENT_TIMESTAMP";
		case SQLITE:
			return "select datetime('now', 'localtime')";
		}
		return null;
	}

}
