package info.bukova.isspst.mail;

import info.bukova.isspst.Constants;
import info.bukova.isspst.EntityUrlResolver;
import info.bukova.isspst.UrlResolverHolder;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EntityMessageBuilder implements MessageBuilder {
	
	private final static Logger logger = LoggerFactory.getLogger(EntityMessageBuilder.class);
	private boolean html;
	private UrlResolverHolder urlResolverHolder;

	public void setHtml(boolean html) {
		this.html = html;
	}

	@Override
	public MailMessage buildMessage(MailMessage template, Object data) {
		MailMessage msg = new MailMessage(template);
		msg.setSubject(replaceProperties(msg.getSubject(), data));
		msg.setText(replaceProperties(msg.getText(), data));
		msg.setHtml(html);
		return msg;
	}
	
	private String replaceProperties(String src, Object data) {
		if (src == null) {
			return "";
		}
		
		int current = 0;
		List<String> properties = new ArrayList<String>();
		boolean found = false;
		String ret = src;
		
		do {
			int openIndex = src.indexOf("[", current);
			int closeIndex = src.indexOf("]", current);
			if (openIndex != -1) {
				String property = src.substring(openIndex + 1, closeIndex);
				if (!properties.contains(property)) {
					properties.add(property);
				}
				found = true;
			} else {
				found = false;
			}
			current = closeIndex + 1;
		} while (found);
		
		for (String p : properties) {
			try {
				if (p.equals(Constants.MAIL_URL_KEYWORD)) {
					ret = ret.replaceAll("\\[" + p + "\\]", getUrl(data));
				} else {
					ret = ret.replaceAll("\\[" + p + "\\]", BeanUtils.getProperty(data, p));
				}
			} catch (IllegalAccessException e) {
				logger.error(e.getMessage());
			} catch (InvocationTargetException e) {
				logger.error(e.getMessage());
			} catch (NoSuchMethodException e) {
				logger.error(e.getMessage());
			} catch (NullPointerException e) {
				logger.error("Null pointer - property: " + p);
			}
		}
		
		return ret;
	}
	
	private String getUrl(Object data) {
		if (urlResolverHolder == null) {
			return "";
		}
		
		EntityUrlResolver res = urlResolverHolder.resolverFor(data.getClass());
		return res.entityUrl(data);
	}

	public void setUrlResolverHolder(UrlResolverHolder urlResolverHolder) {
		this.urlResolverHolder = urlResolverHolder;
	}

}
