package de.lcag.common;

import java.util.List;
import java.util.Map;

import javax.naming.ConfigurationException;

import org.apache.commons.collections4.map.HashedMap;

import routines.LcagStringTools;

public class MappingTable {
	private static final String SOURCE_FIELD_NAME_COLUMN = "Src_FieldName";
	private static final String EXISTING_FIELD_NAME_COLUMN = "Existing_FieldName";

	private HashTable mappingTable = null;
	private Map<String, String> columnMap = new HashedMap<>();

	public MappingTable(String pMapping, String pPairSeperator, String pKeyValueSeperator)
			throws ConfigurationException {
		Map<String, Object> map = LcagStringTools.asMap(pMapping, pPairSeperator, pKeyValueSeperator);
		HashTable table = new HashTable(SOURCE_FIELD_NAME_COLUMN, EXISTING_FIELD_NAME_COLUMN);

		for (String key : map.keySet()) {
			int rowNo = table.newRow();
			Object value = map.get(key);

			table.setCellValue(rowNo, SOURCE_FIELD_NAME_COLUMN, key);
			table.setCellValue(rowNo, EXISTING_FIELD_NAME_COLUMN, value);
		}

		createHashTable(table);
	}

	public MappingTable(HashTable pMappingTable) throws ConfigurationException {
		createHashTable(pMappingTable);
	}

	private void createHashTable(HashTable pMappingTable) throws ConfigurationException {
		this.mappingTable = pMappingTable;

		for (String colName : List.of(SOURCE_FIELD_NAME_COLUMN, EXISTING_FIELD_NAME_COLUMN)) {
			if (!mappingTable.hasColumn(colName)) {
				throw new ConfigurationException(
						String.format("Invalid configuration table: No Column '%s' provided", colName));
			}
		}

		for (int i = 0; i < mappingTable.lenght(); i++) {
			String srcKey = (String) mappingTable.getCellValue(i, SOURCE_FIELD_NAME_COLUMN);
			String existingColumnName = (String) mappingTable.getCellValue(i, EXISTING_FIELD_NAME_COLUMN);

			if (LcagStringTools.isEmpty(srcKey) || LcagStringTools.isEmpty(existingColumnName))
				continue;

			String col = this.columnMap.get(srcKey);

			if (col == null) {
				this.columnMap.put(srcKey, existingColumnName);
			} else if (!col.equals(existingColumnName)) {
				throw new ConfigurationException(String.format(
						"Invalid configuration in table, row %d: Column '%s' already mapped to '%s', cannot map to '%s'",
						i, srcKey, col, existingColumnName));
			}
		}
	}

	public String getColumnLableFor(String pAliasName) {
		String result = columnMap.get(pAliasName);

		return result;
	}

	public String asHTML() {
		return mappingTable.asHTML();
	}

	public int lenght() {
		return mappingTable.lenght();
	}

	public String asCsvData() {
		return mappingTable.asCsvData();
	}

	public String asCSV() {
		return mappingTable.asCSV();
	}

}
