/*-
 * ~~~~~~licensing~~~~~~
 * object-producer-core
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.core.producer.executor.support;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
import ru.entaxy.platform.base.support.CommonUtils;

public class EntaxyObjectPropertiesHelper {

	public static final String PROP_IS_MERGED = "###MERGED";
	public static final String PROP_MAIN_OBJECT_DATA = "###MAIN";
	
	public static boolean isMerged(Map<String, Object> properties) {
		return (properties!=null) && (properties.containsKey(PROP_IS_MERGED)); 
	}
	
	public static Map<String, Object> merge(Map<String, Object> source, Map<String, Object> target){
		Map<String, Object> result = new HashMap<>();
		result.put(PROP_IS_MERGED, true);
		result.putAll(extractObjects(target));
		result.putAll(extractObjects(source));
		result.put(PROP_MAIN_OBJECT_DATA, getMainObjectProperties(target));
		return result;
	} 
	
	public static Map<String, Object> getPropertiesFor(String objectId, String objectType, Map<String, Object> data){
		Map<String, Map<String, Object>> extracted = extractObjects(data);
		return extracted.getOrDefault(createKey(objectId, objectType), new HashMap<>());
	}

	public static Map<String, Object> getMainObjectProperties(Map<String, Object> data){
		Map<String, Map<String, Object>> extracted = extractObjects(data);
		if (extracted.containsKey(PROP_MAIN_OBJECT_DATA))
			return (Map<String, Object>)extracted.get(PROP_MAIN_OBJECT_DATA);
		if (extracted.size() >= 1)
			return (Map<String, Object>)extracted.values().iterator().next();
		return new HashMap<>();
	}
	
	private static String createKey(String objectId, String objectType) {
		return CommonUtils.getValid(objectId, "") + ":" + CommonUtils.getValid(objectType, "");
	}
	
	private static Map<String, Map<String, Object>> extractObjects(Map<String, Object> source){
		Map<String, Map<String, Object>> result = new HashMap<>();
		if (isMerged(source)) {
			for (Entry<String, Object> entry: source.entrySet()) {
				if (PROP_IS_MERGED.equals(entry.getKey()))
					continue;
				if (entry.getValue() instanceof Map) {
					result.put(entry.getKey(), (Map<String, Object>)entry.getValue());
				}
			}
		} else {
			String objectId = source.getOrDefault(FIELDS.OBJECT_ID, "").toString();
			String objectType = source.getOrDefault(FIELDS.OBJECT_TYPE, "").toString();
			if (CommonUtils.isValid(objectId) && CommonUtils.isValid(objectType)) {
				String key = createKey(objectId, objectType);
				result.put(key, source);
			}
		}
		
		return result;
	}
	
}
