/*******************************************************************************
 * Copyright (c) 2005, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal;

import java.sql.Types;
import java.util.HashMap;
import org.eclipse.jpt.utility.JavaType;

/**
 * Helper methods for dealing with the JDBC API.
 */
public final class JDBCTools {


	/**
	 * Return the JDBC type corresponding to the specified class.
	 * @see java.sql.Types
	 */
	public static JDBCType jdbcTypeForClassNamed(String className) {
		JavaToJDBCTypeMapping mapping = javaToJDBCTypeMapping(className);
		return (mapping == null) ? DEFAULT_JDBC_TYPE : mapping.getJDBCType();
	}

	/**
	 * Return the JDBC type corresponding to the specified class.
	 * @see java.sql.Types
	 */
	public static JDBCType jdbcTypeFor(Class<?> javaClass) {
		return jdbcTypeForClassNamed(javaClass.getName());
	}

	/**
	 * Return the JDBC type corresponding to the specified class.
	 * @see java.sql.Types
	 */
	public static JDBCType jdbcTypeFor(JavaType javaType) {
		return jdbcTypeForClassNamed(javaType.getJavaClassName());
	}

	/**
	 * Return the Java type corresponding to the specified JDBC type.
	 * @see java.sql.Types
	 */
	public static JavaType javaTypeForJDBCTypeNamed(String jdbcTypeName) {
		JDBCToJavaTypeMapping mapping = jdbcToJavaTypeMapping(jdbcTypeName);
		return (mapping == null) ? DEFAULT_JAVA_TYPE : mapping.getJavaType();
	}

	/**
	 * Return the Java type corresponding to the specified JDBC type.
	 * @see java.sql.Types
	 */
	public static JavaType javaTypeFor(JDBCType jdbcType) {
		return javaTypeForJDBCTypeNamed(jdbcType.name());
	}

	/**
	 * Return the Java type corresponding to the specified JDBC type.
	 * @see java.sql.Types
	 */
	public static JavaType javaTypeForJDBCTypeCode(int jdbcTypeCode) {
		return javaTypeFor(JDBCType.type(jdbcTypeCode));
	}


	// ********** internal stuff **********


	// ********** JDBC => Java **********

	/**
	 * JDBC => Java type mappings, keyed by JDBC type name (e.g. "VARCHAR")
	 */
	private static HashMap<String, JDBCToJavaTypeMapping> JDBC_TO_JAVA_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
	private static final JavaType DEFAULT_JAVA_TYPE = new SimpleJavaType(java.lang.Object.class);  // TODO Object is the default?


	private static JDBCToJavaTypeMapping jdbcToJavaTypeMapping(String jdbcTypeName) {
		return jdbcToJavaTypeMappings().get(jdbcTypeName);
	}

	private static synchronized HashMap<String, JDBCToJavaTypeMapping> jdbcToJavaTypeMappings() {
		if (JDBC_TO_JAVA_TYPE_MAPPINGS == null) {
			JDBC_TO_JAVA_TYPE_MAPPINGS = buildJDBCToJavaTypeMappings();
		}
		return JDBC_TO_JAVA_TYPE_MAPPINGS;
	}

	private static HashMap<String, JDBCToJavaTypeMapping> buildJDBCToJavaTypeMappings() {
		HashMap<String, JDBCToJavaTypeMapping> mappings = new HashMap<String, JDBCToJavaTypeMapping>();
		addJDBCToJavaTypeMappingsTo(mappings);
		return mappings;
	}

	/**
	 * hard code the default mappings from the JDBC types to the
	 * appropriate Java types
	 * @see java.sql.Types
	 * see "JDBC 3.0 Specification" Appendix B
	 */
	private static void addJDBCToJavaTypeMappingsTo(HashMap<String, JDBCToJavaTypeMapping> mappings) {
		addJDBCToJavaTypeMappingTo(Types.ARRAY, java.sql.Array.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.BIGINT, long.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.BINARY, byte[].class, mappings);
		addJDBCToJavaTypeMappingTo(Types.BIT, boolean.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.BLOB, java.sql.Blob.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.BOOLEAN, boolean.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.CHAR, java.lang.String.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.CLOB, java.sql.Clob.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.DATALINK, java.net.URL.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.DATE, java.sql.Date.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.DECIMAL, java.math.BigDecimal.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.DISTINCT, java.lang.Object.class, mappings);  // ???
		addJDBCToJavaTypeMappingTo(Types.DOUBLE, double.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.FLOAT, double.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.INTEGER, int.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.JAVA_OBJECT, java.lang.Object.class, mappings);  // ???
		addJDBCToJavaTypeMappingTo(Types.LONGVARBINARY, byte[].class, mappings);
		addJDBCToJavaTypeMappingTo(Types.LONGVARCHAR, java.lang.String.class, mappings);
		// not sure why this is defined in java.sql.Types
//		addJDBCToJavaTypeMappingTo(Types.NULL, java.lang.Object.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.NUMERIC, java.math.BigDecimal.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.OTHER, java.lang.Object.class, mappings);	// ???
		addJDBCToJavaTypeMappingTo(Types.REAL, float.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.REF, java.sql.Ref.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.SMALLINT, short.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.STRUCT, java.sql.Struct.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.TIME, java.sql.Time.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.TIMESTAMP, java.sql.Timestamp.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.TINYINT, byte.class, mappings);
		addJDBCToJavaTypeMappingTo(Types.VARBINARY, byte[].class, mappings);
		addJDBCToJavaTypeMappingTo(Types.VARCHAR, java.lang.String.class, mappings);
	}

	private static void addJDBCToJavaTypeMappingTo(int jdbcTypeCode, Class<?> javaClass, HashMap<String, JDBCToJavaTypeMapping> mappings) {
		// check for duplicates
		JDBCType jdbcType = JDBCType.type(jdbcTypeCode);
		Object prev = mappings.put(jdbcType.name(), buildJDBCToJavaTypeMapping(jdbcType, javaClass));
		if (prev != null) {
			throw new IllegalArgumentException("duplicate JDBC type: " + jdbcType.name());
		}
	}

	private static JDBCToJavaTypeMapping buildJDBCToJavaTypeMapping(JDBCType jdbcType, Class<?> javaClass) {
		return new JDBCToJavaTypeMapping(jdbcType, new SimpleJavaType(javaClass));
	}


	// ********** Java => JDBC **********

	/**
	 * Java => JDBC type mappings, keyed by Java class name (e.g. "java.lang.Object")
	 */
	private static HashMap<String, JavaToJDBCTypeMapping> JAVA_TO_JDBC_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
	private static final JDBCType DEFAULT_JDBC_TYPE = JDBCType.type(Types.VARCHAR);  // TODO VARCHAR is the default?


	private static JavaToJDBCTypeMapping javaToJDBCTypeMapping(String className) {
		return javaToJDBCTypeMappings().get(className);
	}

	private static synchronized HashMap<String, JavaToJDBCTypeMapping> javaToJDBCTypeMappings() {
		if (JAVA_TO_JDBC_TYPE_MAPPINGS == null) {
			JAVA_TO_JDBC_TYPE_MAPPINGS = buildJavaToJDBCTypeMappings();
		}
		return JAVA_TO_JDBC_TYPE_MAPPINGS;
	}

	private static HashMap<String, JavaToJDBCTypeMapping> buildJavaToJDBCTypeMappings() {
		HashMap<String, JavaToJDBCTypeMapping> mappings = new HashMap<String, JavaToJDBCTypeMapping>();
		addJavaToJDBCTypeMappingsTo(mappings);
		return mappings;
	}

	/**
	 * hard code the default mappings from the Java types to the
	 * appropriate JDBC types
	 * @see java.sql.Types
	 * see "JDBC 3.0 Specification" Appendix B
	 */
	private static void addJavaToJDBCTypeMappingsTo(HashMap<String, JavaToJDBCTypeMapping> mappings) {
		// primitives
		addJavaToJDBCTypeMappingTo(boolean.class, Types.BIT, mappings);
		addJavaToJDBCTypeMappingTo(byte.class, Types.TINYINT, mappings);
		addJavaToJDBCTypeMappingTo(double.class, Types.DOUBLE, mappings);
		addJavaToJDBCTypeMappingTo(float.class, Types.REAL, mappings);
		addJavaToJDBCTypeMappingTo(int.class, Types.INTEGER, mappings);
		addJavaToJDBCTypeMappingTo(long.class, Types.BIGINT, mappings);
		addJavaToJDBCTypeMappingTo(short.class, Types.SMALLINT, mappings);

		// reference classes
		addJavaToJDBCTypeMappingTo(java.lang.Boolean.class, Types.BIT, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Byte.class, Types.TINYINT, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Double.class, Types.DOUBLE, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Float.class, Types.REAL, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Integer.class, Types.INTEGER, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Long.class, Types.BIGINT, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Short.class, Types.SMALLINT, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.String.class, Types.VARCHAR, mappings);
		addJavaToJDBCTypeMappingTo(java.math.BigDecimal.class, Types.NUMERIC, mappings);
		addJavaToJDBCTypeMappingTo(java.net.URL.class, Types.DATALINK, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Array.class, Types.ARRAY, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Blob.class, Types.BLOB, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Clob.class, Types.CLOB, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Date.class, Types.DATE, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Ref.class, Types.REF, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Struct.class, Types.STRUCT, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Time.class, Types.TIME, mappings);
		addJavaToJDBCTypeMappingTo(java.sql.Timestamp.class, Types.TIMESTAMP, mappings);

		// arrays
		addJavaToJDBCTypeMappingTo(byte[].class, Types.VARBINARY, mappings);
		addJavaToJDBCTypeMappingTo(java.lang.Byte[].class, Types.VARBINARY, mappings);
	}

	private static void addJavaToJDBCTypeMappingTo(Class<?> javaClass, int jdbcTypeCode, HashMap<String, JavaToJDBCTypeMapping> mappings) {
		// check for duplicates
		Object prev = mappings.put(javaClass.getName(), buildJavaToJDBCTypeMapping(javaClass, jdbcTypeCode));
		if (prev != null) {
			throw new IllegalArgumentException("duplicate Java class: " + ((JavaToJDBCTypeMapping) prev).getJavaType().declaration());
		}
	}

	private static JavaToJDBCTypeMapping buildJavaToJDBCTypeMapping(Class<?> javaClass, int jdbcTypeCode) {
		return new JavaToJDBCTypeMapping(new SimpleJavaType(javaClass), JDBCType.type(jdbcTypeCode));
	}


	// ********** constructor **********

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private JDBCTools() {
		super();
		throw new UnsupportedOperationException();
	}


	// ********** member classes **********

	/**
	 * JDBC => Java
	 */
	private static class JDBCToJavaTypeMapping {
		private final JDBCType jdbcType;
		private final JavaType javaType;

		JDBCToJavaTypeMapping(JDBCType jdbcType, JavaType javaType) {
			super();
			this.jdbcType = jdbcType;
			this.javaType = javaType;
		}

		public JDBCType getJDBCType() {
			return this.jdbcType;
		}

		public JavaType getJavaType() {
			return this.javaType;
		}

		public boolean maps(int jdbcTypeCode) {
			return this.jdbcType.code() == jdbcTypeCode;
		}

		public boolean maps(String jdbcTypeName) {
			return this.jdbcType.name().equals(jdbcTypeName);
		}

		public boolean maps(JDBCType type) {
			return this.jdbcType == type;
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			this.appendTo(sb);
			return sb.toString();
		}

		public void appendTo(StringBuilder sb) {
			this.jdbcType.appendTo(sb);
			sb.append(" => ");
			this.javaType.appendDeclarationTo(sb);
		}

	}

	/**
	 * Java => JDBC
	 */
	private static class JavaToJDBCTypeMapping {
		private final JavaType javaType;
		private final JDBCType jdbcType;

		JavaToJDBCTypeMapping(JavaType javaType, JDBCType jdbcType) {
			super();
			this.javaType = javaType;
			this.jdbcType = jdbcType;
		}

		public JavaType getJavaType() {
			return this.javaType;
		}

		public JDBCType getJDBCType() {
			return this.jdbcType;
		}

		public boolean maps(JavaType jt) {
			return this.javaType.equals(jt);
		}

		public boolean maps(String elementTypeName, int arrayDepth) {
			return this.javaType.equals(elementTypeName, arrayDepth);
		}

		public boolean maps(String javaClassName) {
			return this.javaType.describes(javaClassName);
		}

		public boolean maps(Class<?> javaClass) {
			return this.javaType.describes(javaClass);
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			this.appendTo(sb);
			return sb.toString();
		}

		public void appendTo(StringBuilder sb) {
			this.javaType.appendDeclarationTo(sb);
			sb.append(" => ");
			this.jdbcType.appendTo(sb);
		}

	}

}
