/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - 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                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.ui.api.datamart;

import java.text.DateFormat;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.runtime.common.event.IDualData;

/**
 * The Class DatamartFilter.
 */
public class DatamartFilter {
    
	/** The Constant FILTER_PLACEHOLDER. */
	public static final String  FILTER_PLACEHOLDER = "#";

    /**
     * The Enum FilterType.
     */
    public enum FilterType {
        
        /**  single selection via combobox. */
        SINGLE, 
        
        /**  multiple selection via listbox. */
        MULTIPLE, 
        
        /**  cube condition except for something. */
        EXCEPT, 
        
        /**  slice a single value. */
        SINGLESLICER, 
        
        /**  slice multiple values. */
        MULTIPLESLICER, 
        
        /**  hierarchy with single value. */
        SINGLEHIERARCHY, 
        
        /**  hierarchy with multiple values. */
        MULTIPLEHIERARCHY, 

        /**  hierarchy children with single value. */
        SINGLEHIERARCHYCHILDREN, 
        
        /**  hierarchy children with multiple values. */
        MULTIPLEHIERARCHYCHILDREN, 
        
        /**  range of two values. */
        BETWEEN, 
        
        /**  range of two date values. */
        BETWEEN_DATE, 
        
        /**  select by id. */
        BY_ID
    }
    
    /**
     * The Enum FilterType.
     */
    public enum DateTimeFormat {
    	
    	/**  Date Format. */
    	DATE(0, "DATE", "DATE"),
    	
    	/**  Time format. */
    	TIME(1, "TIME", "TIME"),
    	
    	/**  date time format. */
    	DATE_TIME(2, "DATE_TIME", "DATE_TIME");
 
    	private int value;
		private String name;
		private String literal;

		/**
    	 * Only this class can construct instances.
    	 */
    	private DateTimeFormat(int value, String name, String literal) {
    		this.value = value;
    		this.name = name;
    		this.literal = literal;
    	}

    	
    	public int getValue() {
			return value;
		}

		public String getName() {
			return name;
		}

		public String getLiteral() {
			return literal;
		}

		private static final DateTimeFormat[] VALUES_ARRAY =
    			new DateTimeFormat[] {
    				DATE,
    				TIME,
    				DATE_TIME,
    			};
    
    	public static DateTimeFormat get(String literal) {
    		for (int i = 0; i < VALUES_ARRAY.length; ++i) {
    			DateTimeFormat result = VALUES_ARRAY[i];
    			if (result.toString().equals(literal)) {
    				return result;
    			}
    		}
    		return null;
    	}


    }
    
    /**
     * The Enum FilterType.
     */
    public enum DateResolution {
    	
    	SECOND(0, "SECOND", "SECOND"),

    	MINUTE(1, "MINUTE", "MINUTE"),
    	
    	HOUR(2, "HOUR", "HOUR"),

    	DAY(3, "DAY", "DAY"),

    	MONTH(4, "MONTH", "MONTH"),

    	YEAR(5, "YEAR", "YEAR"), 

		UNDEFINED(6, "UNDEFINED", "UNDEFINED");
    	
    	private static final DateResolution[] VALUES_ARRAY =
    			new DateResolution[] {
    					SECOND,
    					MINUTE,
    					HOUR,
    					DAY,
    					MONTH,
    					YEAR,
    					UNDEFINED,
    	};
		private int value;
		private String name;
		private String literal;
    	
		/**
		 * Only this class can construct instances.
		 */
		private DateResolution(int value, String name, String literal) {
    		this.value = value;
    		this.name = name;
    		this.literal = literal;
    	}

		public int getValue() {
			return value;
		}

		public String getName() {
			return name;
		}

		public String getLiteral() {
			return literal;
		}
    	
		public static DateResolution get(String literal) {
			for (int i = 0; i < VALUES_ARRAY.length; ++i) {
				DateResolution result = VALUES_ARRAY[i];
				if (result.toString().equals(literal)) {
					return result;
				}
			}
			return null;
		}

    }
    

    /** The name. */
    private String name;
    
    /** The type. */
    private FilterType type;
    
    /** The sql command to fill data. */
    private String sql;
    
    /** The sql command condition. */
    private String condition;
    
    /** The selector. */
    private IDatamartSelectable selector;
    
    /** The unselected data. */
    private List<IDualData> data;

    /** The selected data. */
    private List<IDualData> selection;
    
    /** optional filter. */
    private boolean optional;

	private IDatamartBetweenInput inputComponent;

	public DateTimeFormat format;

	public DateResolution resolution;

	private IDSLMetadataService dslMetadataService;

	private IUser user;
	
    /**
     * Instantiates a new datamart filter for non date data typed attributes.
     *
     * @param type the type
     * @param dateFormatMap
     * @param name the name
     * @param sql the sql
     */
    public DatamartFilter(IDSLMetadataService dslMetadataService, IUser user, FilterType type, String name, String sql, boolean optional) {
    	this.dslMetadataService = dslMetadataService;
    	this.user = user;
    	this.type = type;
    	this.name = name;
    	this.sql = sql;
    	this.setOptional(optional);
    	data = new ArrayList<>();
    	selection = new ArrayList<>();
	}

    /**
     * Instantiates a new datamart filter for date data typed attributes.
     *
     * @param type the type
     * @param dateFormatMap
     * @param name the name
     * @param sql the sql
     */
    public DatamartFilter(IDSLMetadataService dslMetadataService, IUser user, FilterType type, Map<String, String> dateFormatMap, String name, String sql, boolean optional) {
    	this.dslMetadataService = dslMetadataService;
    	this.user = user;
    	this.type = type;
    	this.name = name;
    	DateTimeFormat format = null;
    	DateResolution resolution = null;
    	if (dateFormatMap != null) {
	    	for (Entry<String, String> entry : dateFormatMap.entrySet()){
	    		if (DateTimeFormat.get(entry.getKey()) != null ){
	    			format = DateTimeFormat.get(entry.getKey());
	    		} 
	    		if (DateResolution.get(entry.getValue()) != null ){
	    			resolution = DateResolution.get(entry.getValue());
	    		} 
	    	}
    	}
    	this.format = format;
    	this.resolution = resolution;
    	this.sql = sql;
    	this.setOptional(optional);
    	data = new ArrayList<>();
    	selection = new ArrayList<>();
    }
    
	/**
	 * Gets the name.
	 *
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * Gets the decorated name.
	 *
	 * @return the decorated name
	 */
	public String getDecoratedName() {
		return DatamartFilter.decorate(name);
	}

	/**
	 * Decorate a string to be replaced later by a selected value/list.
	 *
	 * @param input the input
	 * @return the string
	 */
	public static String decorate(String input) {
		return FILTER_PLACEHOLDER+input+FILTER_PLACEHOLDER;
	}
	
	/**
	 * Sets the name.
	 *
	 * @param name the new name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets the type.
	 *
	 * @return the type
	 */
	public FilterType getType() {
		return type;
	}

	/**
	 * Sets the type.
	 *
	 * @param type the new type
	 */
	public void setType(FilterType type) {
		this.type = type;
	}

	/**
	 * Gets the sql.
	 *
	 * @return the sql
	 */
	public String getSql() {
		return sql;
	}

	/**
	 * Sets the sql.
	 *
	 * @param sql the new sql
	 */
	public void setSql(String sql) {
		this.sql = sql;
	}

	/**
	 * Gets the condition.
	 *
	 * @return the condition
	 */
	public String getCondition() {
		return condition;
	}

	/**
	 * Sets the condition.
	 *
	 * @param condition the new condition
	 */
	public void setCondition(String condition) {
		this.condition = condition;
	}
	
	/**
	 * Gets the selector.
	 *
	 * @return the selector
	 */
	public IDatamartSelectable getSelector() {
		return selector;
	}

	/**
	 * Sets the selector.
	 *
	 * @param selector the new selector
	 */
	public void setSelector(IDatamartSelectable selector) {
		this.selector = selector;
	}

	/**
	 * Gets the input component.
	 *
	 * @return the input component
	 */
	public IDatamartBetweenInput getBetweenInputComponent() {
		return inputComponent;
	}
	
	/**
	 * Sets the input component.
	 *
	 * @param inputComponent the new input component
	 */
	public void setBetweenInputComponent(IDatamartBetweenInput inputComponent) {
		this.inputComponent = inputComponent;
	}
	
	/**
	 * Gets the data.
	 *
	 * @return the data
	 */
	public List<IDualData> getData() {
		return data;
	}

	public boolean isOptional() {
		return optional;
	}

	public void setOptional(boolean optional) {
		this.optional = optional;
	}

	/**
	 * Sets the data.
	 *
	 * @param data the new data
	 */
	public void setData(List<IDualData> data) {
		if(data != null) {
			this.data.addAll(data);
		}
	}

	/**
	 * Adds the item.
	 *
	 * @param item the item
	 */
	public void addItem(IDualData item) {
		data.add(item);
	}
	
	/**
	 * Removes an item from data.
	 *
	 * @param item the item
	 */
	public void removeItem(IDualData item) {
		data.remove(item);
	}
	
	/**
	 * Clear data.
	 */
	public void clearData() {
		data.clear();
	}
	
	/**
	 * Adds the item.
	 *
	 * @param value the value
	 */
	public void addItem(String value, boolean asString) {
		if(value != null) {
			IDualData item = new DatamartData();
			item.setFormattedValue(value);
			item.setSelectionValue(value);
			item.asString(asString);
			data.add(item);
		}
	}

	/**
	 * Adds the item.
	 *
	 * @param value the value
	 * @param selectValue the select value
	 */
	public void addItem(String value, String selectValue, boolean asString) {
		if(value != null) {
			IDualData item = new DatamartData();
			item.setFormattedValue(value);
			item.setSelectionValue(selectValue);
			item.asString(asString);
			data.add(item);
		}
	}
	
	/**
	 * Adds the olap item.
	 *
	 * @param hierarchy the hierarchy
	 * @param uniqueName the unique name
	 */
	public void addOlapItem(String hierarchy, String uniqueName) {
		if(uniqueName != null) {
			IDualData item = new DatamartData();
			item.setHierarchy(hierarchy);
			item.setSelectionValue(uniqueName);
			String[] parts = uniqueName.replace("[", "").replace("]", "").split("\\.");
			List<String> values = new ArrayList<>();
			for(int i=0;i<parts.length;i++) {
				if(hierarchy.contains(parts[i])) {
//					values.add(dslMetadataService.translate(user.getLocale().toLanguageTag(), parts[i]));
				} else {
					values.add(parts[i]);
				}
			}
			// take the last element as caption
			item.setFormattedValue(values.stream().collect(Collectors.joining(" ")));
			if(!item.getFormattedValue().contains("null")) {
				data.add(item);
			}
		}
	}

	/**
	 * Gets the selected data.
	 *
	 * @return the selected data
	 */
	public List<IDualData> getSelectedData() {
		return selection;
	}

	/**
	 * Sets the selected data.
	 *
	 * @param selection the new selected data
	 */
	public void setSelectedData(List<IDualData> selection) {
		if(selection != null) {
			this.selection.addAll(selection);
		}
	}
	
	/**
	 * Adds the selected item.
	 *
	 * @param item the item
	 */
	public void addSelectedItem(IDualData item) {
		selection.add(item);
	}
	
	/**
	 * Adds the selected item.
	 *
	 * @param value the value
	 */
	public void addSelectedItem(String value) {
		IDualData item = new DatamartData();
		item.setFormattedValue(value);
		item.setSelectionValue(value);
		selection.add(item);
	}

	/**
	 * Removes the selected item.
	 *
	 * @param item the item
	 */
	public void removeSelectedItem(IDualData item) {
		selection.remove(item);
	}
	
	/**
	 * Clear selected data.
	 */
	public void clearSelectedData() {
		selection.clear();
	}
	
	/**
	 * Can select data. Returns true if a filter matched the given selected data and selects the selector.
	 *
	 * @param selectedData the selected data
	 * @param single the single
	 * @param olap the olap
	 * @return true, if successful
	 */
	@SuppressWarnings("unchecked")
	public boolean canSelectData(Map<EventDispatcherDataTag, Object> selectedData, boolean single, boolean olap) {
		for(EventDispatcherDataTag tag : selectedData.keySet()) {
			if(tag == EventDispatcherDataTag.ID) { 
				return false;
			} else if(tag == EventDispatcherDataTag.LIST) {
				return selectData((List<String>)selectedData.get(tag));
			}
		}
		return false;
	}
	
	/**
	 * Select data.
	 *
	 * @param selected the selected
	 * @param olap the olap
	 * @return true, if successful
	 */
	private boolean selectData(List<String> selected) {
		boolean firstAdd = true; 
		for(String item:selected) {
			switch(type) {
			case SINGLE:
			case MULTIPLE: 
				for(IDualData dd : data) {
					if(dd.getSelectionValue().equals(item)) {
						if(firstAdd) {
							firstAdd = false;
							clearSelectedData();
						}
						addSelectedItem(dd);
						return true;
					}
				}
				break;
			case EXCEPT: 
			case SINGLESLICER: 
			case MULTIPLESLICER: 
			case SINGLEHIERARCHY:
			case MULTIPLEHIERARCHY:
			case SINGLEHIERARCHYCHILDREN:
			case MULTIPLEHIERARCHYCHILDREN:
				if(!item.contains("[") && !data.isEmpty()) {
					String prefix = data.get(0).getHierarchyWithBrackets()+".";
					String suffix = ".["+item.replace(".", "].[")+"]";
					for(IDualData dd : data) {
						if(dd.getSelectionValue().startsWith(prefix) &&  dd.getSelectionValue().endsWith(suffix)) {
							if(firstAdd) {
								firstAdd = false;
								clearSelectedData();
							}
							addSelectedItem(dd);
							return true;
						}
					}
				}
				break;
			default:
				return false;
			}
		}
		return false;
	}

}
