/**
 ********************************************************************************
 * Copyright (c) 2020 Eclipse APP4MC contributors.
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 ********************************************************************************
 */

package org.eclipse.app4mc.atdb.metrics;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.IntStream;

import org.eclipse.nebula.widgets.nattable.data.AutomaticSpanningDataProvider;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ISpanningDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.group.performance.RowGroupHeaderLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.DataCell;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Table;

public final class DBResultRowDataProvider implements IRowDataProvider<List<String>>, ISpanningDataProvider {
	
	static DBResultRowDataProvider of(final ResultSet rs, final List<Integer> groupByColumnIndices) throws SQLException {
		return new DBResultRowDataProvider(rs, groupByColumnIndices);
	}
	
	private final int columnCount;
	private final BiMap<Integer, List<String>> rowIndex2DataValue;
	private final IDataProvider columnsHeaderDataProvider;
	private final IDataProvider rowHeaderDataProvider;
	private final ISpanningDataProvider rowSpanningDataProvider;
	private final List<Integer> groupByColumnIndices;
	
	private DBResultRowDataProvider(final ResultSet rs, final List<Integer> groupByColumnIndices) throws SQLException {
		this.rowIndex2DataValue = HashBiMap.create();
		final ResultSetMetaData rsmd = rs.getMetaData();
		final int colCount = rsmd.getColumnCount();
		final List<String> columneHeaderNames = new ArrayList<>();
		for(int i = 1; i <= colCount; i++) {
			columneHeaderNames.add(rsmd.getColumnName(i));
		}
		while (rs.next()) {
			final List<String> resultRow = new ArrayList<>();
			for(int i = 1; i <= colCount; i++) {
				resultRow.add(rs.getString(i));
			}
			this.rowIndex2DataValue.put(rs.getRow() - 1, resultRow);
		}
		this.columnsHeaderDataProvider = new DefaultColumnHeaderDataProvider(columneHeaderNames.toArray(new String[colCount]));
		this.rowSpanningDataProvider = new AutomaticSpanningDataProvider(this, false, true);
		this.rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.rowSpanningDataProvider);
		this.columnCount = colCount;
		this.groupByColumnIndices = Collections.unmodifiableList(groupByColumnIndices);
	}

	@Override
	public String getDataValue(final int columnIndex, final int rowIndex) {
		return this.rowIndex2DataValue.get(rowIndex).get(columnIndex);
	}

	@Override
	public void setDataValue(final int columnIndex, final int rowIndex, final Object newValue) {
		throw new UnsupportedOperationException(Messages.DBViewer_immutableResultError);
	}

	@Override
	public int getColumnCount() {
		return this.columnCount;
	}

	@Override
	public int getRowCount() {
		return this.rowIndex2DataValue.size();
	}

	@Override
	public List<String> getRowObject(final int rowIndex) {
		return this.rowIndex2DataValue.get(rowIndex);
	}

	@Override
	public int indexOfRowObject(final List<String> rowObject) {
		return this.rowIndex2DataValue.inverse().get(rowObject);
	}
	
	public IDataProvider getColumnHeaderDataProvider() {
		return this.columnsHeaderDataProvider;
	}
	
	public IDataProvider getRowHeaderDataProvider() {
		return this.rowHeaderDataProvider;
	}
	
	public void initializeGroups(final RowGroupHeaderLayer rowGroupHeaderLayer) {
		if (this.groupByColumnIndices.isEmpty()) {
			// no groups to initialize
			return;
		}
		IntStream.range(rowGroupHeaderLayer.getLevelCount(), this.groupByColumnIndices.size()).forEach(i -> rowGroupHeaderLayer.addGroupingLevel());
		Table<Integer, String, Integer> levelGroupTuple2StartIndex = HashBasedTable.create();
		Map<Integer, String> level2currentGroup = new LinkedHashMap<>();
		for(final Entry<Integer,List<String>> entry:this.rowIndex2DataValue.entrySet()) {
			final int absIndex = entry.getKey();
			final List<String> row = entry.getValue();
			for(int level = 0; level < this.groupByColumnIndices.size(); level++) {
				final int columnIndex = this.groupByColumnIndices.get(level);
				final String groupCellValue = row.get(columnIndex);
				if (!levelGroupTuple2StartIndex.contains(level, groupCellValue)) {
					if (level2currentGroup.containsKey(level)) {
						// current group ends here
						final String currentGroupName = level2currentGroup.get(level);
						final int startIndex = levelGroupTuple2StartIndex.get(level, currentGroupName);
						rowGroupHeaderLayer.addGroup(level, currentGroupName, startIndex, absIndex - startIndex);
						levelGroupTuple2StartIndex.remove(level, currentGroupName);
					}
					// new group starts here
					level2currentGroup.put(level, groupCellValue);
					levelGroupTuple2StartIndex.put(level, groupCellValue, absIndex);
				}
			}
		}
		for(int level = 0; level < this.groupByColumnIndices.size(); level++) {
			if (level2currentGroup.containsKey(level)) {
				// finish groups
				final String currentGroupName = level2currentGroup.get(level);
				final int startIndex = levelGroupTuple2StartIndex.get(level, currentGroupName);
				rowGroupHeaderLayer.addGroup(level, currentGroupName, startIndex, this.rowIndex2DataValue.size() - startIndex);
				levelGroupTuple2StartIndex.remove(level, currentGroupName);
			}
		}
	}

	@Override
	public DataCell getCellByPosition(int columnPosition, int rowPosition) {
		return this.rowSpanningDataProvider.getCellByPosition(columnPosition, rowPosition);
	}

}
