package com.topsunit.query.binding;

import com.huigou.data.query.executor.SQLExecutorDao;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @param <T>
 * @author yonghuan
 */
public class MapperProxy<T> implements InvocationHandler {


    private final InvokeContext invokeContext;
    private final List<InvokeStrategy> invokeStrategies;

    public MapperProxy(Class<T> mapperInterface, String xml, SQLExecutorDao sqlExecutor) {
        invokeContext = new InvokeContextImpl(mapperInterface, xml, sqlExecutor);
        invokeStrategies = new ArrayList<>(4);
        invokeStrategies.add(new SelectSqlInvokeStrategy(new DefaultSqlTranslator(), new DefaultParameterParser()));
        invokeStrategies.add(new ObtainSqlInvokeStrategy());
        invokeStrategies.add(new ObtainQueryDescriptorInvokeStrategy());
        invokeStrategies.add(new SqlQueryInvokeStrategy(new CglibQueryRequestFactory()));
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return invokeStrategies.stream()
                .filter(invokeStrategy -> invokeStrategy.supports(invokeContext, method, args))
                .map(invokeStrategy -> invokeStrategy.invoke(invokeContext, method, args))
                .findFirst()
                .get();
    }
}
