/**
 *                                                                            
 * 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 v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.xtext.datamart.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.osbp.preferences.EnumDatabaseVendor;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.event.IDualData;
import org.eclipse.osbp.ui.api.datamart.DatamartFilter;
import org.eclipse.osbp.ui.api.datamart.IDataMart;

/**
 * The Class ADatamart.
 *
 * @param <C> the generic type
 */
@SuppressWarnings("all")
public abstract class ADatamart<C> implements IDataMart {
	
	/**
	 * Connect.
	 *
	 * @return the c
	 */
	public abstract C connect();
	
	/**
	 * Gets the axis map.
	 *
	 * @return the axis map
	 */
	public abstract HashMap<Integer,ArrayList<String>> getAxisMap();
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ui.api.datamart.IDataMart#getIdMap()
	 */
	public abstract HashMap<String, EType> getIdMap();
	
	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ui.api.datamart.IDataMart#getTypesMap()
	 */
	public abstract HashMap<String, EType> getTypesMap();
	
	/**
	 * Disconnect.
	 *
	 * @return returns results from datamart. If filler text is enabled, the result will be generated via filler text.
	 * @see {@link #enableFillerText(boolean)}
	 */
	public abstract void disconnect();
	
	/** The db vendor. */
	protected EnumDatabaseVendor dbVendor = null;
    
    /** The filter map. */
    private ArrayList<DatamartFilter> filterMap = null;
    
    /** 
     * @return the map with all filters, which has to be initialized once
     */
    @Override
    public ArrayList<DatamartFilter> getFilters() {
    	if	(filterMap == null) {
    		if(getPersistenceUnit() != null) {
	    		String jndiName = ProductConfiguration.getPersistenceUnitJndiName(getPersistenceUnit());
	    		dbVendor = ProductConfiguration.getDataSource(jndiName).getDatabaseVendor();
    		}
    		filterMap = initializeFilterMap();
    	}
    	return filterMap;
    }

    /**
     * Gets the vendor specific sql.
     *
     * @param filter the filter
     * @return the vendor sql
     */
    protected String getVendorSql(DatamartFilter filter) {
    	if(dbVendor != null) {
    		return dbVendor.applySqlSpecifications(filter.getSql());
    	}
    	return filter.getSql();
    }
    
    /**
     * Gets the vendor specific 'to date' sql method prefix.
     *
     * @return the vendor 'to date' sql method prefix
     */
    protected String getVendorToDateSQLMethod() {
    	if(dbVendor != null) {
    		return dbVendor.getToDateSQLMethod();
    	}
    	return "to_date";
    }
    
    /**
     * Gets the vendor specific 'to timestamp' sql method prefix.
     *
     * @return the vendor 'to timestamp' sql method prefix
     */
    protected String getVendorToTimestampSQLMethod() {
    	if(dbVendor != null) {
    		return dbVendor.getToTimestampSQLMethod();
    	}
    	return "to_timestamp";
    }
    
    /**
     * Gets the filters count.
     *
     * @return count of filters
     */
    protected int getFiltersCount() {
    	return getFilters().size();
    }

    /**
     * Gets the persistence unit.
     *
     * @return the persistence unit used
     */
    abstract protected String getPersistenceUnit();
    
    /**
     * Initialize filter map.
     *
     * @return the initialized filter map
     */
    abstract protected ArrayList<DatamartFilter> initializeFilterMap();

	/**
	 * Compute conditions from selected data according to the filter type.
	 */
    @Override
	public void computeConditions() {
		ArrayList<DatamartFilter> filters = getFilters();
		if (filters != null) {
			DatamartFilter firstFilter = null;
			List<List<String>> filterGroup = new ArrayList<List<String>>();
			for (DatamartFilter filter : filters) {
				filter.setCondition(null);
				switch (filter.getType()) {
				case BY_ID:
					if(!filter.getSql().isEmpty()) {
						filter.setCondition(filter.getName()+"="+filter.getSql());
					}
					break;
				case SINGLE:
				case SINGLEHIERARCHY:
				case EXCEPT:
				case SINGLESLICER:
					if(!filter.getSelectedData().isEmpty()) {
						filter.setCondition(filter.getSelectedData().get(0).getDatabaseSelectionValue());
					} else {	// failsafe - but only if filter is optional
						filter.setCondition("'*'");
					}
					break;
				case BETWEEN:
				case BETWEEN_DATE:
					if(filter.getBetweenInputComponent() != null) {
						if ((!filter.getBetweenInputComponent().getFrom().isEmpty()) && (!filter.getBetweenInputComponent().getUntil().isEmpty())){
							filter.setCondition(filter.getName() + " BETWEEN '" + filter.getBetweenInputComponent().getFrom() + "' AND '" + filter.getBetweenInputComponent().getUntil() + "'");
						} else {
							filter.setCondition("1=1");
						}
					} else {	// failsafe - but only if filter is optional
						filter.setCondition("'*'");
					}
					break;
				case MULTIPLE:
				case MULTIPLEHIERARCHY:
					String selection = "";
					for(IDualData item : filter.getSelectedData()) {
						if (item != null) {
							if (!selection.isEmpty()) {
								selection += ",";
							}
							selection += item.getDatabaseSelectionValue();
						}
					}
					filter.setCondition(selection);
					break;
				case MULTIPLESLICER:
					// all multiple slicer filters are accumulated to the first filter multiple slicer filter
					List<String> myList = new ArrayList<String>();
					for (IDualData item : filter.getSelectedData()) {
						if (item != null) {
							myList.add(item.getDatabaseSelectionValue());
						}
					}
					filterGroup.add(myList);
					if (firstFilter == null) {
						firstFilter = filter;
					} else {
						filter.setCondition("<empty>");
					}
					break;
				}
			}
			if(firstFilter != null) {
				// calculate every permutation of selection as slices must be created
				List<List<String>> permutations = new ArrayList<List<String>>();
				int numEntries = 1;
				for (List<String> list : filterGroup) {
					numEntries *= list.size();
				}
				for (int i = 0; i < numEntries; i++) {
					permutations.add(new ArrayList<String>());
				}
				for (List<String> itemList : filterGroup) {
					Iterator<String> iterator = itemList.iterator();
					if (iterator.hasNext()) {
						for (List<String> entry : permutations) {
							entry.add(iterator.next());
							if (!iterator.hasNext()) {
								iterator = itemList.iterator();
							}
						}
					}
				}
				String set = "";
				boolean firstSet = true;
				for (List<String> permutation : permutations) {
					boolean firstTuple = true;
					String tuple = "";
					for (String item : permutation) {
						if (firstTuple) {
							firstTuple = false;
						} else {
							tuple += ",";
						}
						tuple += item;
					}
					if (firstSet) {
						firstSet = false;
					} else {
						set += ",";
					}
					set += "(" + tuple + ")";
				}
				firstFilter.setCondition("{" + set + "}");
			}
		}
	}
}
