/**
 *                                                                            
 *  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.olap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import elemental.json.JsonFactory;
import elemental.json.impl.JreJsonArray;
import elemental.json.impl.JreJsonFactory;
import elemental.json.impl.JreJsonObject;

public class CellSetToD3JsonConverter {
	
	private static final String KEY_CHILDREN="children";
	private static final String KEY_NAME="name";
	private static final String KEY_TOOLTIPNAME="tooltipName";
	private static JsonFactory factory = new JreJsonFactory();

	public static String getD3JsonString(DerivedCellSet cxCellSet) {
	    // generate a new result component
	    if (cxCellSet == null) {
	    	return "";
	    }
	    
		ArrayList<Integer> coordinateSystem = new ArrayList<>();
    	// create a multidimensional coordinate system against the cellSet
    	for	(int axis = 0; axis < cxCellSet.getAxes().size(); axis++) {
    		coordinateSystem.add(0);
    	}
	    List<Integer> coordinate = new ArrayList<>(coordinateSystem);
	    // add styles to page for the axis's custom styles
	    List<String> dataColumns = getDataColumnNameList(cxCellSet);
		
	    JreJsonArray jsonArrayStructure = new JreJsonArray(factory);
	    
	    // for every data row
	    for	(DerivedPosition rows : cxCellSet.getAxes().get(1).getPositions()) {
	    	// row Data
	    	coordinate.set(1, rows.getOrdinal());
	    	// fill in the row members for the row axis
	    	for (DerivedMember member : rows.getMembers()) {
	    		JreJsonObject childrenListMap = new JreJsonObject(factory);
	    		String[] tokens = member.getUniqueName().split("\\]\\.\\[");
	    		LinkedList<String> tokenList = new LinkedList<>(Arrays.asList(tokens));
	    		// create a concatenated name of all members for the data column
	    		childrenListMap.put(KEY_TOOLTIPNAME, member.getUniqueName().replace("[", "").replace("]", "").replace(".", "-"));
	    		// create a name from the last member for the data column
	    		childrenListMap.put(KEY_NAME, tokenList.getLast().replace("[", "").replace("]", ""));
		    	for	(DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) {
		    		coordinate.set(0, columns.getOrdinal());
		    		childrenListMap.put(dataColumns.get(columns.getOrdinal()), cxCellSet.getCell(coordinate).getFormattedValue());
		    	}
	    	    // creation of a LinkedHashMap structure
	    	    createJsonMapStructure(jsonArrayStructure, tokenList, childrenListMap);
	    	}
	    }
	    JreJsonObject jsonMap;
	    // to ensure that only exist one root node
	    if (jsonArrayStructure.length() > 0){
	    	jsonMap = new JreJsonObject(factory);
			jsonMap.put(KEY_NAME, "RootNode");
			jsonMap.put(KEY_CHILDREN, jsonArrayStructure); 
	    } else {
	    	jsonMap = (JreJsonObject) jsonArrayStructure.get(0);
	    }
	    return jsonMap.toString();
	}

	public static List<String> getDataColumnNameList(DerivedCellSet cxCellSet) {
		// create a table column for all data column
	    List<String> dataColumns = new LinkedList<>();
	    for	(DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) {
	    	String title = null;
	    	for (DerivedMember member : columns.getMembers()) {
	    		if	(title == null) {
	    			title = member.getCaption();
	    		}
	    		else {
	    			title += " "+member.getCaption();
	    		}
	    	}
	    	dataColumns.add(title);
	    }
		return dataColumns;
	}

	private static JreJsonArray createJsonMapStructure(JreJsonArray jsonArray, LinkedList<String> tokenList, JreJsonObject childrenListMap) {
		String tokenStr = tokenList.get(0).replace("]", "").replace("[", "");
		tokenList.removeFirst();
		JreJsonArray jsonChildrenArray = null;
		JreJsonObject jsonMap = null;
		// if a jsonMap with the current tokenStr already exist, then no new jsonChildrenArray is created, 
		// but the existing jsonChildrenArray within the children key of the jsonMap is used.
		for (int i=0; i < jsonArray.length(); i++) {
			jsonMap = (JreJsonObject) jsonArray.get(i);
			if (tokenStr.equals(jsonMap.get(KEY_NAME))) {
				jsonChildrenArray = (JreJsonArray)jsonMap.get(KEY_CHILDREN);
				break;
			}
		}
		
		// only checking existing jsonChildrenArray, 
		// because jsonMap can be the last map of the jsonArray if exists.
		// So if no jsonChildrenArray exist it has to be created with a new jsonMap.
		if (jsonChildrenArray==null) {
			jsonMap = new JreJsonObject(factory);
			jsonMap.put(KEY_NAME, tokenStr);
			jsonArray.set(jsonArray.length(), jsonMap);
			jsonChildrenArray = new JreJsonArray(factory);
		}
		if (tokenList.size()==1){
			JreJsonArray jsonRowsDataArray;
			//check if children with JreJsonArray exist
			if (jsonMap.hasKey(KEY_CHILDREN)){
				jsonRowsDataArray = (JreJsonArray) jsonMap.get(KEY_CHILDREN);
			} else {
				jsonRowsDataArray = new JreJsonArray(factory);
			}
			jsonRowsDataArray.set(jsonArray.length(), childrenListMap);
			jsonMap.put(KEY_CHILDREN, jsonRowsDataArray);
		} else {
			jsonChildrenArray = createJsonMapStructure(jsonChildrenArray, tokenList, childrenListMap);
			jsonMap.put(KEY_CHILDREN, jsonChildrenArray);
		}
		
		return jsonArray;
	}

}
