package com.infoteria.asteria.flowlibrary2.mapper.string;

import com.infoteria.asteria.flowengine2.execute.ExecuteContext;
import com.infoteria.asteria.flowlibrary2.mapper.Function;
import com.infoteria.asteria.flowlibrary2.mapper.MapperException;
import com.infoteria.asteria.value.Value;

public class CONCATENATE extends Function {
	
	private static final String FUNCTION_NAME = "CONCATENATE";
	private static final String PROPERTY_SEPARATOR = "Separator";
	private static final String PROPERTY_ENABLE_METACHARACTER = "EnableMetaCharacter";
	private static final String PROPERTY_NO_SEP_WHEN_NULL = "NoSeparatorWhenEmpty";
	
	public String getFunctionName() { return FUNCTION_NAME;}
	
	protected void internalInit() {
		registProperty(PROPERTY_SEPARATOR, Value.TYPE_STRING, false);
		registProperty(PROPERTY_ENABLE_METACHARACTER, Value.TYPE_BOOLEAN, false);
		registProperty(PROPERTY_NO_SEP_WHEN_NULL, Value.TYPE_BOOLEAN, false, new Value(false));
	}
	
	public boolean checkInputCount() {
		return getInputList().size() > 0;
	}
	
	public void execute(ExecuteContext context, Value[] in, Value out) throws MapperException {
		String separatorProp = getPropertyString(PROPERTY_SEPARATOR);
		if (getPropertyBoolean(PROPERTY_ENABLE_METACHARACTER)) {
			separatorProp = CONST.replaceMetaCharacter(separatorProp);
		}
		StringBuilder buff = new StringBuilder(1024);
		boolean bAdd = false;
		for(int i=0; i<in.length; i++) {
			String s = in[i].strValue();
			if (s.length() == 0 && getPropertyBoolean(PROPERTY_NO_SEP_WHEN_NULL))
				continue;
			if (bAdd)
				buff.append(separatorProp);
			buff.append(s);
			bAdd = true;
		}
		out.setValue(buff.toString());
	}
	
	protected void postCompile() throws MapperException {
		if (getPropertyBoolean(PROPERTY_ENABLE_METACHARACTER)) {
			Value v = getProperty(PROPERTY_SEPARATOR);
			if (v == null)
				return;
			
			v.setValue(CONST.replaceMetaCharacter(v.strValue()));
		}
	}
}
