package ru.yandex.direct.api.v5.ws.enpointmapping;

import java.lang.reflect.Method;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;

import ru.yandex.direct.api.v5.ws.ApiMessage;
import ru.yandex.direct.api.v5.ws.annotation.ApiMethod;


/**
 * Мap methods tagged with {@link ApiMethod} annotation.
 */
public class ApiMethodEndpointMapping
        extends AbstractAnnotationMethodEndpointMapping<ApiMethodEndpointMappingKey> {
    /**
     * Gets a lookup key for supplied method by processing annotation {@link ApiMethod}.
     *
     * @param method the method
     * @return the lookup key to map passed method or {@code null} if it's unable to detect key
     */
    @Override
    protected ApiMethodEndpointMappingKey getLookupKeyForMethod(Method method) {
        ApiMethod apiMethod = AnnotationUtils.findAnnotation(method, ApiMethod.class);
        if (apiMethod == null) {
            return null;
        }
        return new ApiMethodEndpointMappingKey(apiMethod.service(), apiMethod.operation());
    }

    /**
     * Detects the endpoint lookup key for the passed message context
     *
     * @param messageContext holder of the request message which will be used to obtaining of lookup key.
     * @return the lookup key or null for unsupported message types
     * @throws Exception if something goes wrong
     */
    @Override
    protected ApiMethodEndpointMappingKey getLookupKeyForMessage(MessageContext messageContext) throws Exception {
        if (!(messageContext.getRequest() instanceof ApiMessage)) {
            return null;
        }
        ApiMessage requestMessage = (ApiMessage) messageContext.getRequest();
        String service = requestMessage.getService();
        String operation = requestMessage.getOperation();
        if (service == null || operation == null) {
            return null;
        }
        return new ApiMethodEndpointMappingKey(requestMessage.getService(), requestMessage.getOperation());
    }

}
