package com.agilex.healthcare.schedulingmanager.mdws.connection;

import com.agilex.healthcare.mobilehealthplatform.domain.PatientIdentifier;
import com.agilex.healthcare.utility.NullChecker;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class RequestMessage {
	private String messageId = UUID.randomUUID().toString();
	protected String messageType = null;
	private String parentId = null;
	private Map<String, Object> parameters = new HashMap<String, Object>();

	public RequestMessage() {
	}

	public RequestMessage(RequestMessage parent) {
		this.setParentId(parent.getMessageId());
	}

	public String getType() {
		return this.messageType;
	}

	public void setType(String type) {
		this.messageType = type;
	}

	public String getMessageId() {
		return messageId;
	}

	public String getParentId() {
		return parentId;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	@SuppressWarnings("unchecked")
	public <T> T getValue(String key) {
		return (T) parameters.get(key);
	}

	public String getValueAsString(String key) {
		return getValue(key);
	}

	public void setValue(String key, Object value) {
		parameters.put(key, value);
	}

	public RequestMessage createChildCopy() {
		RequestMessage copy = new RequestMessage();
		copy.messageType = this.messageType;
		copy.parentId = this.messageId;
		for (String key : parameters.keySet()) {
			Object value = parameters.get(key);
			Object valueToImport;
			if (value instanceof PatientIdentifier) {
				valueToImport = ((PatientIdentifier) value).createCopy();
			} else {
				valueToImport = value;
			}
			copy.setValue(key, valueToImport);
		}
		return copy;
	}

	@Override
	public String toString() {
		return debugOutput(false);
	}

	public String debugOutput(boolean includeAllParameters) {
		String template = "[%s=%s]";

		StringBuilder sb = new StringBuilder();
		sb.append(String.format(template, "id", this.getMessageId()));
		if (NullChecker.isNotNullish(this.getParentId()))
			sb.append(String.format(template, "parent", this.getParentId()));
		sb.append(String.format(template, "type", this.getType()));

		for (String key : parameters.keySet()) {
			sb.append(String.format(template, key, this.getValue(key)));
		}

		return sb.toString();
	}

}