package eu.eudat.models.rda.mapper;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.utilities.json.JsonSearcher;
import eu.eudat.models.rda.DatasetId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class DatasetIdRDAMapper {
	private static final Logger logger = LoggerFactory.getLogger(DatasetIdRDAMapper.class);

	/*public static DatasetId toRDA(UUID id) {
		DatasetId rda = new DatasetId();
		rda.setIdentifier(id.toString());
		rda.setType(DatasetId.Type.OTHER);

		return rda;
	}*/

	public static DatasetId toRDA(List<JsonNode> nodes) {
		DatasetId data = new DatasetId();
		for (JsonNode node: nodes) {
			String rdaProperty = node.get("rdaProperty").asText();
			String rdaValue = node.get("value").asText();
			if(rdaValue == null || rdaValue.isEmpty()){
				continue;
			}

			ObjectMapper mapper = new ObjectMapper();
			try {
				Map<String, Object> values = mapper.readValue(rdaValue, HashMap.class);
				if (!values.isEmpty()) {
					values.entrySet().forEach(entry -> finalRDAMap(data, entry.getKey(), (String) entry.getValue()));
				} else {
					finalRDAMap(data, rdaProperty, rdaValue);
				}
			} catch (IOException e) {
				logger.warn(e.getMessage() + ".Passing value as is");
				finalRDAMap(data, rdaProperty, rdaValue);

			}

		}

		if (data.getIdentifier() != null && data.getType() != null) {
			return data;
		}
		return null;
	}

	private static void finalRDAMap(DatasetId rda, String property, String value) {
		if (value != null) {
			for (DatasetIdProperties datasetIdProperties : DatasetIdProperties.values()) {
				if (property.contains(datasetIdProperties.getName())) {
					switch (datasetIdProperties) {
						case IDENTIFIER:
							rda.setIdentifier(value);
							break;
						case TYPE:
							rda.setType(DatasetId.Type.fromValue(value));
							break;
					}
				}
			}
		}


	}

	public static Map<String, String> toProperties(DatasetId rda, JsonNode node) {
		Map<String, String> properties = new HashMap<>();

		List<JsonNode> idNodes = JsonSearcher.findNodes(node, "rdaProperty", "dataset.dataset_id");

		for (JsonNode idNode: idNodes) {
			for (DatasetIdProperties datasetIdProperties : DatasetIdProperties.values()) {
				if (idNode.get("rdaProperty").asText().endsWith(datasetIdProperties.getName())) {
					switch (datasetIdProperties) {
						case IDENTIFIER:
							properties.put(idNode.get("id").asText(), rda.getIdentifier());
							break;
						case TYPE:
							properties.put(idNode.get("id").asText(), rda.getType().value());
							break;
					}

				}
			}
		}
		return properties;
	}

	private enum DatasetIdProperties {
		IDENTIFIER("identifier"),
		TYPE("type");

		private final String name;

		DatasetIdProperties(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}
	}
}
