/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.xtext.reportdsl.common;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;

import org.eclipse.birt.core.data.DataType;
import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;

import org.eclipse.osbp.ui.api.datamart.IDataMart.EType;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute;
import org.eclipse.osbp.xtext.datamartdsl.jvmmodel.DatamartDSLJvmModelInferrer;



public enum DataTypes {
	
	STRING(DataType.STRING_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, "String", Types.CHAR, String.class),
	BIGDECIMAL(DataType.DECIMAL_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, "BigDecimal", Types.DECIMAL, BigDecimal.class, Double.class, Float.class),
	TIMESTAMP(DataType.DATE_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_DATETIME, "Timestamp", Types.TIMESTAMP, Timestamp.class),
	BLOB(DataType.BLOB_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_BLOB, "Blob", Types.BLOB /*, .class*/),
	BLOBMAPPING(DataType.BLOB_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_BLOB, "blobMapping", Types.BLOB /*, .class*/),
// ???	CLOB(DesignChoiceConstants.COLUMN_DATA_TYPE_CLOB, "Clob", Types.CLOB /*, .class*/),
	INTEGER(DataType.INTEGER_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER, "Integer", Types.INTEGER, Integer.class),
	INT(DataType.INTEGER_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER, "Int", Types.INTEGER, Integer.class),
/* ??? why not this ???	*/LONG(DataType.DECIMAL_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, "Long", Types.DECIMAL, Long.class),
//	LONG(DataType.INTEGER_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER, "Long", Types.INTEGER, Long.class, Integer.class, Short.class),
	SHORT(DataType.INTEGER_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER, "Short", Types.INTEGER, Short.class),
	DATE(DataType.SQL_DATE_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_DATE, "Date", Types.DATE, Date.class),
	TIME(DataType.SQL_TIME_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_TIME, "Time", Types.TIME, Time.class),
	BOOLEAN(DataType.BOOLEAN_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_BOOLEAN, "Boolean", Types.BOOLEAN, Boolean.class),
	DOUBLE(DataType.DOUBLE_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_FLOAT, "Double", Types.DOUBLE, Double.class, Float.class),
	FLOAT(DataType.DOUBLE_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_FLOAT, "Float", Types.DOUBLE, Float.class),
	OBJECT(DataType.JAVA_OBJECT_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_JAVA_OBJECT, "Object", Types.JAVA_OBJECT /*, .class*/),
	BINARY(DataType.BINARY_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_BLOB, "Binary", Types.BINARY /*, .class*/),
	@SuppressWarnings("deprecation")
	ANY(DataType.ANY_TYPE, DesignChoiceConstants.COLUMN_DATA_TYPE_ANY, "any", Types.OTHER);
	
	private DataTypes(int birtDataTypeId, String nativeDataTypeName, String odaScalaDataTypeName, int sqlDataTypeId, Class<?>...supportedClasses) {
		fBirtDataTypeId = birtDataTypeId;
		fNativeOdaDataTypeName = nativeDataTypeName;
		fOdaScalaDataTypeName = odaScalaDataTypeName;
		fNativeOdaDataTypeId = sqlDataTypeId;
		fSupportedClasses = supportedClasses;
	}
	
	public String getNativeOdaDataTypeName() {
		return fNativeOdaDataTypeName;
	}
	public String getOdaScalaDataTypeName() {
		return fOdaScalaDataTypeName;
	}
	public int getNativeOdaDataTypeId() {
		return fNativeOdaDataTypeId;
	}
	public int getBirtDataTypeId() {
		return fBirtDataTypeId;
	}
	public String getBirtDataTypeName() {
		return DataType.getName(fBirtDataTypeId);
	}

	/**
	 * @see http://docs.oracle.com/cd/E13190_01/liquiddata/docs81/xquery/datatypes.html
	 * @see http://docs.oracle.com/cd/B19306_01/java.102/b14188/datamap.htm#CHDBJAGH
	 * @param sqlPlSqlDataType
	 * @return
	 */
	public static DataTypes typeofSqlPlSQLDataType(String sqlPlSqlDataType) {
		switch (sqlPlSqlDataType.toUpperCase()) {
			case "CHAR":
			case "CHARACTER":
			case "STRING":
			case "VARCHAR":
			case "VARCHAR2":
				return STRING; // oracle.sql.CHAR / java.lang.String
			case "NCHAR":
			case "NVARCHAR2":
				return STRING; // oracle.sql.NCHAR / oracle.sql.NString
			case "NCLOB":
				return STRING; // oracle.sql.NCLOB / oracle.sql.NCLOB
			case "RAW":
			case "LONG RAW":
				return BLOB; // oracle.sql.RAW / byte[]
			case "LONG":
				return LONG;
			case "BINARY_INTEGER":
			case "NATURAL":
			case "NATURALN":
			case "PLS_INTEGER":
			case "POSITIVE":
			case "POSITIVEN":
			case "SIGNTYPE":
			case "INT":
			case "INTEGER":
				return INTEGER; // oracle.sql.NUMBER / int
			case "SHORT":
				return SHORT; // oracle.sql.NUMBER / int
			case "DEC":
			case "DECIMAL":
			case "NUMBER":
			case "NUMERIC":
				return BIGDECIMAL; // oracle.sql.NUMBER / java.math.BigDecimal
			case "DOUBLE PRECISION":
			case "FLOAT":
				return BIGDECIMAL; // oracle.sql.NUMBER / double
			case "SMALLINT":
				return INTEGER; // oracle.sql.NUMBER / int
			case "REAL":
				return BIGDECIMAL; // oracle.sql.NUMBER / float
			case "DATE":
				return DATE; // oracle.sql.DATE / java.sql.Timestamp
			case "TIMESTAMP":
			case "TIMESTAMP WITH TZ":
			case "TIMESTAMP WITH LOCAL TZ":
				return TIMESTAMP; // oracle.sql.TIMESTAMP / oracle.sql.TIMESTAMPTZ / oracle.sql.TIMESTAMPLTZ / java.sql.Timestamp
			case "INTERVAL YEAR TO MONTH":
			case "INTERVAL DAY TO SECOND":
				return STRING; // String
//			case "ROWID":
//			case "UROWID":
//				// oracle.sql.ROWID / oracle.sql.ROWID
			case "BOOLEAN":
				return BOOLEAN; // boolean / boolean
			case "CLOB":
				return STRING; // oracle.sql.CLOB / java.sql.Clob
			case "BLOB":
				return BLOB; // oracle.sql.BLOB / java.sql.Blob
			case "BFILE":
				return BLOB; // oracle.sql.BFILE / oracle.sql.BFILE
//Object types / Generated class / Generated class
//SQLJ object types / Java class defined at type creation / Java class defined at type creation
//OPAQUE types / Generated or predefined class / Generated or predefined class
//RECORD types / Through mapping to SQL object type / Through mapping to SQL object type
//Nested table, VARRAY / Generated class implemented using oracle.sql.ARRAY / java.sql.Array
//Reference to object type / Generated class implemented using oracle.sql.REF / java.sql.Ref
//REF CURSOR / java.sql.ResultSet / java.sql.ResultSet
//Index-by tables / Through mapping to SQL collection / Through mapping to SQL collection
//Scalar (numeric or character) / Index-by tables / Through mapping to Java array / Through mapping to Java array
//User-defined subtypes / Same as for base type / Same as for base type
		}
		return ANY;
	}
	
	public static DataTypes typeOf(String dataType) {
		if	(dataType != null) {
		for	(DataTypes step : values()) {
			if	(dataType.equalsIgnoreCase(step.fNativeOdaDataTypeName)) {
				return step;
			}
			if	(dataType.equalsIgnoreCase(step.fOdaScalaDataTypeName)) {
				return step;
			}
			if	(dataType.equalsIgnoreCase(step.getBirtDataTypeName())) {
				return step;
				}
			}
		}
		return ANY;
	}
	
	public static DataTypes typeOfNativeDataType(String nativeDataType) {
		for	(DataTypes step : values()) {
			if	(nativeDataType.equalsIgnoreCase(step.fNativeOdaDataTypeName)) {
				return step;
			}
		}
		return ANY;
	}

	public static DataTypes typeOfOdaScalaDataType(String odaScalaDataType) {
		for	(DataTypes step : values()) {
			if	(odaScalaDataType.equalsIgnoreCase(step.fOdaScalaDataTypeName)) {
				return step;
			}
		}
		return ANY;
	}

	public static DataTypes typeOfBirtDataType(String birtDataType) {
		for	(DataTypes step : values()) {
			if	(birtDataType.equalsIgnoreCase(step.getBirtDataTypeName())) {
				return step;
			}
		}
		return ANY;
	}

	public static DataTypes typeOfNativeOdaDataType(int nativeOdaDataType) {
		for	(DataTypes step : values()) {
			if	(nativeOdaDataType == step.fNativeOdaDataTypeId) {
				return step;
			}
		}
		return ANY;
	}

	public static DataTypes typeOfBirtDataType(int birtDataType) {
		for	(DataTypes step : values()) {
			if	(birtDataType == step.fBirtDataTypeId) {
				return step;
			}
		}
		return ANY;
	}

	/**
	 * @see {@link DatamartDSLJvmModelInferrer#evaluateExpression(org.eclipse.osbp.xtext.datamartdsl.Expression, org.eclipse.osbp.xtext.datamartdsl.DatamartEntity)}
	 * DatamartEntity.properties == DatamartAttribute
	 * <pre>
	if (element instanceof DatamartAttribute) {
		evaluation = '''«(element as DatamartAttribute).getAttributeName(false, entity)»'''
		var type = (element as DatamartAttribute).propertyRef.type
		var typeName = ""
		if (type != null && (type instanceof LDataType) && (type as LDataType).jvmTypeReference!=null){
			typeName = (type as LDataType).jvmTypeReference.simpleName
		} else {
			typeName = type.name
		}
		if (!typeName.equals("String")) {
			evaluation = '''to_char(«evaluation»)'''
		}   
	}
		</pre>
	 * 
	 */
	public static DataTypes typeOfOdaScalaDataType(DatamartAttribute datamartAttribute) {
		LEntityAttribute entityAttribute = datamartAttribute.getAttributeRef();
		LScalarType scalarType = null;
		Class<?> findClass = null;
		String typeName = null;
		if	(entityAttribute != null) {
			scalarType = entityAttribute.getType();
		}
		if	(scalarType instanceof LDataType) {
			findClass = scalarType.getClass();
			if	(findClass != null) {
				typeName = findClass.getSimpleName();
			}
		}
		else if	(scalarType != null) {
			typeName = scalarType.getName();
		}
		return typeOfNativeDataType(typeName);
	}

	public static DataTypes typeFor(LDataType dataType) {
		if	(dataType == null) {
			return DataTypes.ANY;
		}
		if	(dataType.isDate()) {
			return DataTypes.DATE;
		}
		return typeOf(dataType.getName());
	}

	public static DataTypes typeFor(EType eType) {
		switch (eType) {
			case BOOLEAN:
			case BOOLEAN_CHECKBOX:
				return DataTypes.BOOLEAN;
			case DATE:
				return DataTypes.DATE;
			case FLOAT:
				return DataTypes.FLOAT;
			case DOUBLE:
				return DataTypes.DOUBLE;
			case INTEGER:
				return DataTypes.INT;
			case SHORT:
				return DataTypes.SHORT;
			case LONG:
				return DataTypes.LONG;
			case STRING:
			case RICHTEXTAREA:
				return DataTypes.STRING;
			case TIME:
				return DataTypes.TIME;
			case TIMESTAMP:
				return DataTypes.TIMESTAMP;
			case BLOPMAPPING:
				return DataTypes.BLOBMAPPING;
			case LENUM:
				return DataTypes.INT;
		default:
			break;
		}
		return DataTypes.ANY;
	}

	public static DataTypes typeFor(Object object) {
		if	(object instanceof EType) {
			return typeFor((EType)object);
		}
		else if	(object instanceof LDataType) {
			return typeFor((LDataType)object);
		}
		else if	(object == null) {
			return ANY;
		}
		else {
			DataTypes retcode = typeFor(object.getClass());
			if	(retcode == null) {
				return ANY;
			}
			else {
				return retcode;
			}
		}
	}

	public static DataTypes typeFor(Class<?> findClass) {
		for	(DataTypes step : values()) {
			if	(findClass.equals(DataType.getClass(step.fBirtDataTypeId))) {
				return step;
			}
			else if	(step.fSupportedClasses != null) {
				for	(Class<?> supportedClass : step.fSupportedClasses) {
					if	(findClass.equals(supportedClass)) {
						return step;
					}
				}
			}
		}
		return ANY;
	}
	
	/** see {@link org.eclipse.birt.core.data.DataType} */
	private final int fBirtDataTypeId;
	/** see <code>org.eclipse.osbp.xtext.reportdsl.oda.datamart/plugin.xml:dataTypeMapping</code> */
	private final int fNativeOdaDataTypeId;
	/** see <code>org.eclipse.osbp.xtext.reportdsl.oda.datamart/plugin.xml:dataTypeMapping</code>
	 *  see for example {@link org.eclipse.birt.report.model.api.elements.DesignChoiceConstants.COLUMN_DATA_TYPE_STRING}
	 */
	private final String fNativeOdaDataTypeName;
	/** see {@link java.sql.Types} has to be defined in org.eclipse.osbp.xtext.reportdsl.ord.datamart / pugin.xml */
	private final String fOdaScalaDataTypeName;
	private final Class<?>[] fSupportedClasses;
}
