package com.hammurapi.extract;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;

public class MethodExtractor<T, V, C> extends ExtractorBase<T, V, C> implements	Extractor<T, V, C> {
	
	private Method method;
	private Set<Integer> parameterIndices;

	public MethodExtractor(double initialCost, TimeUnit costUnit, Method method) {
		super(initialCost, costUnit);
		this.method = method;
		Set<Integer> pi = new TreeSet<Integer>();	
		for (int i=0, l=method.getParameterTypes().length; i<l; ++i) {
			pi.add(i);
		}
		parameterIndices = Collections.unmodifiableSet(pi);
	}

	@Override
	public Set<Integer> parameterIndices() {
		return parameterIndices;
	}

	@Override
	public boolean isContextDependent() {
		return Modifier.isStatic(method.getModifiers());
	}

	@SuppressWarnings("unchecked")
	@Override
	protected V extractInternal(
			C context,
			Map<C, Map<Extractor<T, ? super V, C>, ? super V>> cache, 
			T... obj) {
		try {
			return (V) method.invoke(context, obj);
		} catch (IllegalAccessException e) {
			throw new ExtractorException(e);
		} catch (InvocationTargetException e) {
			throw new ExtractorException(e);
		}
	}
	

}
