package org.apache.slide.projector.value;

import java.util.Map;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.Store;
import org.apache.commons.contract.constraints.Evaluatable;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.engine.ProcessorManager;
import org.apache.slide.projector.processor.process.Process;

public class Any implements Evaluatable {

	private URI processorUri;
    private String result;
	private String storeId;
    private String key;
    private String domain;
    private Object input;

	/**
	 * @param processor
	 * @param result
	 * @param store
	 * @param key
	 * @param domain
	 */
	public Any(String processor, Object input, String result, String storeId, String key, String domain) {
		if ( processor != null ) {
			this.processorUri = new URIValue(processor);
			this.input = input;
		}
		this.result = result;
		this.storeId = storeId;
		this.key = key;
		this.domain = domain;
	}

	public String getDomain() {
		return domain;
	}

	public Object getInput() {
		return input;
	}

	public String getKey() {
		return key;
	}
	
	public URI getProcessorUri() {
		return processorUri;
	}
	
	public String getResult() {
		return result;
	}
	
	public String getStoreId() {
		return storeId;
	}
	
	public Object evaluate(Context context) throws Exception {
		Object value = null;
		if ( key != null ) {
			if ( storeId.equals(Projector.NO_STORE) ) {
				storeId = Projector.STEP_STORE;
			} 
			String evaluatedKey = Process.evaluateKey(key, context);
			Store store = context.getStore(storeId);
			if ( store != null ) { 
				if ( domain != null ) {
					Map map = (Map)store.get(domain, context);
					if ( map != null ) {
						value = map.get(evaluatedKey);
					}
				} else {
					value = store.get(evaluatedKey, context);
				}
			}
		}
        if ( processorUri != null ) {
        	if ( input != null ) {
        		value = input;
        	}
            value = ProcessorManager.getInstance().process(processorUri, value, result, context);
        }
        return value;
	}
}