package org.eclipse.osbp.authentication.account.datamarts;

import com.vaadin.ui.Notification;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.osbp.bpm.api.BPMTaskSummary;
import org.eclipse.osbp.core.api.persistence.IPersistenceService;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.event.IDualData;
import org.eclipse.osbp.runtime.common.historized.UUIDHist;
import org.eclipse.osbp.runtime.common.i18n.ITranslator;
import org.eclipse.osbp.ui.api.datamart.DatamartData;
import org.eclipse.osbp.ui.api.datamart.DatamartFilter;
import org.eclipse.osbp.ui.api.datamart.DatamartPrimary;
import org.eclipse.osbp.ui.api.datamart.IDataMart;
import org.eclipse.osbp.ui.api.date.SimpleDateFormatter;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.user.User;
import org.eclipse.osbp.xtext.datamart.common.AEntityDatamart;
import org.eclipse.osbp.xtext.datamart.common.DatamartDtoMapper;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedAxis;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCellSet;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedMember;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedPosition;
import org.eclipse.osbp.xtext.datamart.common.sql.SqlCellSet;
import org.junit.Test;
import org.olap4j.Axis;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;

@SuppressWarnings("serial")
public class UserAccountDatamart extends AEntityDatamart {
  private static Logger log = org.slf4j.LoggerFactory.getLogger("datamarts");
  
  private IUser user;
  
  private Map<String, Map<String, String>> dateFilterAttributeProperties = new LinkedHashMap<String, Map<String, String>>();
  
  private String statement = "select UserAccount.USER_NAME as \"userName\",UserAccount.EMAIL as \"email\",UserAccount.POSITION as \"position\",UserAccount.PROFILEIMAGE as \"profileimage\",UserAccount.NOT_REGISTERED as \"notRegistered\",UserAccount.id as \"__UserAccount__ID__\" from USER_ACCOUNT UserAccount";
  
  private DatamartDtoMapper datamartDtoMapper = new DatamartDtoMapper()
    .add("org.eclipse.osbp.authentication.account.dtos.UserAccountDto", "id", EType.NONE, "__UserAccount__ID__")
    ;
  
  private Connection connection = null;
  
  private Map<Integer, ArrayList<String>> axisMap = new LinkedHashMap<Integer,ArrayList<String>>() {{
    		put(0,new ArrayList<String>() {{
    		add("userName");
    		add("email");
    		add("position");
    		add("profileimage");
    		add("notRegistered");
    		add("__UserAccount__ID__");
    		}});
    }};
  
  private Map<String, String> aliasMap = new LinkedHashMap<String,String>() {{
    	put("userName","org.eclipse.osbp.authentication.account.entities.UserAccount.userName");
    	put("email","org.eclipse.osbp.authentication.account.entities.UserAccount.email");
    	put("position","org.eclipse.osbp.authentication.account.entities.UserAccount.position");
    	put("profileimage","org.eclipse.osbp.authentication.account.entities.UserAccount.profileimage");
    	put("notRegistered","org.eclipse.osbp.authentication.account.entities.UserAccount.notRegistered");
    }};
  
  private Map<String, IDataMart.AttributeVisibility> hiddenMap = new LinkedHashMap<String,AttributeVisibility>() {{
    }};
  
  private Map<String, IDataMart.EType> idMap = new LinkedHashMap<String,EType>() {{
    			put("__UserAccount__ID__", EType.STRING);
    }};
  
  private Map<String, DatamartPrimary> primaryList = new LinkedHashMap<String, DatamartPrimary>() {{
    			put("__UserAccount__ID__", new DatamartPrimary("__UserAccount__ID__", "id", "org.eclipse.osbp.authentication.account.entities.UserAccount", false));
    }};
  
  private Map<String, IDataMart.EType> typesMap = new LinkedHashMap<String,EType>() {{
    	put("UserAccount.userName", EType.STRING);
    	put("UserAccount.email", EType.STRING);
    	put("UserAccount.position", EType.STRING);
    	put("UserAccount.profileimage", EType.BLOPMAPPING);
    	put("UserAccount.notRegistered", EType.BOOLEAN);
    }};
  
  private Map<String, String> typesProp = new LinkedHashMap<String, String>() {{
    	put("position", "");
    	put("profileimage", "2");
    }};
  
  private Map<String, String> resultAttributes = new LinkedHashMap<String,String>();
  
  private boolean moreToLoad = false;
  
  public Map<String, IDataMart.EType> getIdMap() {
    return this.idMap;
  }
  
  public Map<String, DatamartPrimary> getPrimaryList() {
    return this.primaryList;
  }
  
  public Map<Integer, ArrayList<String>> getAxisMap() {
    return this.axisMap;
  }
  
  public Map<String, String> getAliasMap() {
    return this.aliasMap;
  }
  
  public Map<String, IDataMart.AttributeVisibility> getHiddenMap() {
    return this.hiddenMap;
  }
  
  public Map<String, String> getTypesProp() {
    return this.typesProp;
  }
  
  public IUser getUser() {
    return this.user;
  }
  
  public void setUser(final IUser user) {
    this.user = user;
  }
  
  public List<Object> getPrimaryListKeys(final String columnId) {
    return primaryList.get(columnId).getKeys();
    
  }
  
  public boolean contains(final Object key) {
    for(String primaryKeyName:idMap.keySet()) {
    	if(primaryList.get(primaryKeyName).getKeys().contains(key)) {
    		return true;
    	}
    }
    return false;
    
  }
  
  protected ArrayList<DatamartFilter> initializeFilterMap() {
    return new ArrayList<DatamartFilter>() {{
    add(new DatamartFilter(DatamartFilter.MultipleType.SINGLE, DatamartFilter.FilterType.BY_ID, "UserAccount.id", "UserAccount.id","", false));
    }};
    
  }
  
  public String getPrimaryFilterId() {
    return "UserAccount.id";
    
  }
  
  @Override
  public void clearCache() {
    
  }
  
  @Override
  public String getResultAttribute(final String attributeName) {
    return resultAttributes.get(attributeName);
  }
  
  public Map<String, IDataMart.EType> getTypesMap() {
    return typesMap;
    
  }
  
  public String getPersistenceUnit() {
    return "authentication";
    
  }
  
  public Connection connect() {
    if (connection == null) {   			
    	try {
    		connection = org.eclipse.osbp.authentication.account.datamarts.DatamartsServiceBinder.getPersistenceService().getPersistenceUnitConnection(getPersistenceUnit());
    	} catch (SQLException e) {
    		log.error("{}", e);
    		return (connection);
    	}
    }
    return (connection);
  }
  
  public void disconnect() {
    if (connection != null) {   			
    	try {
    		connection.close();
    		connection = null;
    	} catch (SQLException e) {
    		log.error("{}", e);
    	}
    }
  }
  
  public boolean isMoreToLoad() {
    return moreToLoad;
  }
  
  public String insertCondition(final String filteredStatement, final String condition) {
    int index = filteredStatement.indexOf("order by");
    if(index > -1) {
    	return filteredStatement.substring(0, index-1) + condition + filteredStatement.substring(index-1); 
    } else {
    	return filteredStatement + condition;
    }
  }
  
  public void renderFilters() {
    connect();
    if (connection != null) {
    	for (DatamartFilter filter : getFilters()) {
    		if((DatamartFilter.FilterType.BY_ID != filter.getType()) && (DatamartFilter.FilterType.BY_HISTUUID != filter.getType()) && (DatamartFilter.FilterType.BETWEEN != filter.getType()) && (DatamartFilter.FilterType.BETWEEN_DATE != filter.getType())) {
    			try (ResultSet rs = connection.createStatement().executeQuery(getVendorSql(filter))){
    				if (rs != null) {
    					while (rs.next()) {
    					 		int type = rs.getMetaData().getColumnType(1);
    					 		switch (type) {
    					 			case java.sql.Types.DATE:
    					 			    Date date = rs.getDate(1);
    					 			    if (date != null) {
    					 					if (user == null) {
    					 						filter.addItem(date.toString(), vendorConvertToDateSQL( date ), false);
    					 					} else {
    					 						filter.addItem(SimpleDateFormatter.getFormat("LONGDATE", user.getLocale()).format(date), vendorConvertToDateSQL( date ), false);
    					 					}
    					 				}
    					 				break;
    					 			case java.sql.Types.TIMESTAMP:
    					 				Timestamp timestamp = rs.getTimestamp(1);
    					 				if (timestamp != null) {
    					 					if (user == null) {
    					 						filter.addItem(timestamp.toString(), vendorConvertToTimestampSQL( timestamp ), false);
    					 					} else {
    					 						filter.addItem(SimpleDateFormatter.getFormat("LONGDATE", user.getLocale()).format(timestamp), vendorConvertToTimestampSQL( timestamp ), false);
    					 					}
    					 				}
    					 				break;
    					 			case java.sql.Types.DECIMAL:
    					 				BigDecimal bigDecimal = rs.getBigDecimal(1);
    					 				if (bigDecimal != null) {
    					 					filter.addItem(bigDecimal.toPlainString(), bigDecimal.toPlainString(), false);
    					 				}
    					 				break;
    					 			case java.sql.Types.NUMERIC:
    					 			case java.sql.Types.DOUBLE:
    					 				filter.addItem(Double.toString(rs.getDouble(1)), Double.toString(rs.getDouble(1)), false);
    					 				break;
    					 			case java.sql.Types.INTEGER:
    					 			case java.sql.Types.BIGINT:
    					 				filter.addItem(Integer.toString(rs.getInt(1)), Integer.toString(rs.getInt(1)), false);
    					 				break;
    					 			case java.sql.Types.FLOAT:
    					 				filter.addItem(Float.toString(rs.getFloat(1)), Float.toString(rs.getFloat(1)), false);
    					 				break;
    					 			case java.sql.Types.CHAR:
    					 			case java.sql.Types.NCHAR:
    					 			case java.sql.Types.NVARCHAR:
    					 			case java.sql.Types.VARCHAR:
    							case java.sql.Types.LONGVARCHAR: 
    										filter.addItem(rs.getString(1), rs.getString(1), true);
    										break;
    								}
    					}
    				}
    			} catch (SQLException e) {
    				log.error("{}", e);
    			}
    		}
    	}
    }
    disconnect();
  }
  
  public String applyFilters() {
    String filteredStatement = statement;
    computeConditions();
    for (DatamartFilter filter : getFilters()) {
    	if (DatamartFilter.FilterType.BY_ID == filter.getType() || DatamartFilter.FilterType.BY_HISTUUID == filter.getType()) {
    		if(filter.getCondition() != null) {
    			if	(!filteredStatement.toLowerCase().contains(" where ")) {
    				if	((" "+filter.getCondition()).toLowerCase().contains("where ")) {
    					filteredStatement = insertCondition(filteredStatement, " "+filter.getCondition());
    				}
    				else {
    					filteredStatement = insertCondition(filteredStatement, " where "+filter.getCondition());
    				}
    			}
    			else {
    				if	(filter.getCondition().trim().toLowerCase().startsWith("and ") ||
    					 filter.getCondition().trim().toLowerCase().startsWith("or ") ) {
    					filteredStatement = insertCondition(filteredStatement, filter.getCondition());
    				}
    				else {
    					filteredStatement = insertCondition(filteredStatement, " and "+filter.getCondition());
    				}
    			}
    		}
    	}
    	else {
    		if(filter.getCondition() != null) {
    		   	filteredStatement = filteredStatement.replace(filter.getDecoratedName(), filter.getCondition());
    		} else {
    			log.debug("condition was null in UserAccount:{}", filteredStatement);
    			return "";
    		}
    	}
    }
    log.debug("UserAccount:"+filteredStatement);
    return filteredStatement;
  }
  
  public DerivedCellSet getResults() {
    return getResults(false, null, null);
  }
  
  public DerivedCellSet getResults(final boolean limited, final Class operativeDtoClass, final List<IDto> operativeDtos) {
    SqlCellSet cellSet = null;
    java.sql.ResultSetMetaData metaData = null;
    connect();
    if (connection != null) {
    	String query = applyFilters();
    	if (query.length()>0) {
    		try {
    			log.debug("statement:{} limited:{}", query, limited);
    			Statement stmt = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    			if(limited) {
    				stmt.setMaxRows(500);
    				stmt.setFetchSize(500);
    			}
    			ResultSet rs = stmt.executeQuery(query);
    			if(!rs.isClosed()) {
    				metaData = rs.getMetaData();
    				cellSet = new SqlCellSet(rs, metaData, user, resultAttributes, getAxisMap(), getIdMap(), getAliasMap(), getHiddenMap(), datamartDtoMapper, operativeDtoClass, operativeDtos, getPrimaryList(), org.eclipse.osbp.authentication.account.datamarts.DatamartsServiceBinder.getUserAccessService(), false);
    				moreToLoad = false;
    				if(limited && cellSet.getFetchedRows() == 500) {
    					moreToLoad = true;
    				}
    				disconnect();
    				return (new DerivedCellSet(cellSet,
    					metaData,
    					org.eclipse.osbp.authentication.account.datamarts.DatamartsServiceBinder.getDSLMetadataService(), user));
    			}
    		}
    		catch (java.sql.SQLException e) {
    			log.error("Statement: {}  error {}", query, e);
    		}
    	}
    }
    disconnect();
    return null;
  }
  
  @Test
  public void TestUserAccount() {
    renderFilters();
    org.junit.Assert.assertNotNull(getResults(true, null, null));
  }
}
