package org.apache.slide.projector.processor.process;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.Result;
import org.apache.commons.contract.Store;
import org.apache.commons.contract.StoreException;
import org.apache.commons.i18n.LocalizedError;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.processor.ProcessException;
import org.apache.slide.projector.store.AbstractStore;

class ResultConfiguration {
    private static Logger logger = Logger.getLogger(ResultConfiguration.class.getName());

    private String storeId = Projector.NO_STORE;
    private String name, key, domain;
    private long timeout = -1;

    public ResultConfiguration(String name, String storeId, String domain, String key, long timeout) {
        this.name = name;
        this.storeId = storeId;
        this.domain = domain;
        this.key = key;
        this.timeout = timeout;
    }

    public String getStoreId() {
        return storeId;
    }

    public String getDomain() {
    	return domain;
    }
    
    public String getKey() {
        return key;
    }

    public String getName() {
        return name;
    }

    protected void storeValue(Object value, Store stepStore, Result result, Context context) throws ProcessException {
    	if ( value == null ) {
    		throw new ProcessException(new LocalizedError("valueToStoreNotFound"));
    	}
        Store resultStore = stepStore;
        if ( storeId.equals(Projector.OUTPUT_STORE )) {
            result.addResultEntry(key, value);
        } else {
            if ( !storeId.equals(Projector.NO_STORE ) ) {
            	resultStore = context.getStore(storeId);
            }
            if ( resultStore == null ) {
        		throw new ProcessException(new LocalizedError("storeNotAvailable", new String[] { key, storeId }));
            } else {
                try {
                    String evaluatedKey = Process.evaluateKey(key, context);
                    if ( evaluatedKey != null ) {
                    	if ( domain != null ) {
                    		Map map = (Map)resultStore.get(domain, context);
                			if ( map == null ) {
                				map = new HashMap();
                			}
                			map.put(evaluatedKey, value);
                			evaluatedKey = domain;
                			value = map;
                    	}
                    	if ( timeout != -1 ) {
                    		((AbstractStore)resultStore).put(evaluatedKey, value, timeout, context);
                    	} else {
                    		resultStore.put(evaluatedKey, value, context);
                    	}
                    }
                } catch ( StoreException e ) {
            		throw new ProcessException(new LocalizedError("storingResultFailed"), e);
                }
            }
        }
    }
}