/*******************************************************************************
 * Copyright (c) 2009 Shane Clarke.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Shane Clarke - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.jaxws.core.annotations.validation;

import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.CLASS_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.FAULT_BEAN;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.HEADER;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.LOCAL_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.MODE;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.OPERATION_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.PART_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.PORT_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.RESPONSE_SUFFIX;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.SERVICE_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.TARGET_NAMESPACE;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import javax.xml.ws.WebFault;

import org.apache.xerces.util.XMLChar;
import org.eclipse.jst.ws.annotations.core.processor.AbstractAnnotationProcessor;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.jaxws.core.JAXWSCoreMessages;
import org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;

import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.AnnotationValue;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.type.ReferenceType;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.util.SourcePosition;

public class UniqueNamesRule extends AbstractAnnotationProcessor {
    private static Pattern pattern = Pattern.compile("arg\\d++"); //$NON-NLS-1$

    @Override
    public void process() {
        AnnotationTypeDeclaration webServiceDeclaration = (AnnotationTypeDeclaration) environment
        .getTypeDeclaration(WebService.class.getName());

        Collection<Declaration> annotatedTypes = environment
        .getDeclarationsAnnotatedWith(webServiceDeclaration);


        for (Declaration declaration : annotatedTypes) {
            if (declaration instanceof TypeDeclaration) {
                TypeDeclaration typeDeclaration = (TypeDeclaration) declaration;
                validateNameAttributes(typeDeclaration);
                checkOperationNames(typeDeclaration.getMethods());
                checkWrapperAndFaultBeanNames(typeDeclaration.getMethods());
                checkDocumentBareMethods(typeDeclaration.getMethods());
                checkMethodParameters(typeDeclaration.getMethods());
            }
        }
    }

    private void validateNameAttributes(TypeDeclaration typeDeclaration) {
        AnnotationMirror webService = AnnotationUtils.getAnnotation(typeDeclaration, WebService.class);
        checkAttributeValue(webService, WebService.class.getSimpleName(), NAME);
        checkAttributeValue(webService, WebService.class.getSimpleName(), PORT_NAME);
        checkAttributeValue(webService, WebService.class.getSimpleName(), SERVICE_NAME);

        Collection<? extends MethodDeclaration> methods = typeDeclaration.getMethods();
        for (MethodDeclaration methodDeclaration : methods) {
            AnnotationMirror webMethod = AnnotationUtils.getAnnotation(methodDeclaration, WebMethod.class);
            checkAttributeValue(webMethod, WebMethod.class.getSimpleName(), OPERATION_NAME);

            Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
            for (ParameterDeclaration parameterDeclaration : parameters) {
                AnnotationMirror webParam = AnnotationUtils.getAnnotation(parameterDeclaration, WebParam.class);
                checkAttributeValue(webParam, WebParam.class.getSimpleName(), NAME);
                checkAttributeValue(webParam, WebParam.class.getSimpleName(), PART_NAME);
            }
        }
    }

    private void checkAttributeValue(AnnotationMirror annotationMirror, String annotationName, String attributeName) {
        if (annotationMirror != null) {
            AnnotationValue annotationValue = AnnotationUtils.getAnnotationValue(annotationMirror, attributeName);
            if (annotationValue != null) {
                if (annotationValue.toString().trim().length() == 0) {
                    printError(annotationValue.getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.EMPTY_ATTRIBUTE_VALUE, new Object[] { annotationName, attributeName }));
                } else if (!XMLChar.isValidName(annotationValue.toString())) {
                    printError(annotationValue.getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.INVALID_NCNAME_ATTRIBUTE, new Object[] { annotationName,
                                    attributeName,  annotationValue.toString() }));
                }
            }
        }
    }

    private void checkOperationNames(Collection<? extends MethodDeclaration> methods) {
        Map<Declaration, QName> nameMap = new HashMap<Declaration, QName>();
        for (MethodDeclaration methodDeclaration : methods) {
            nameMap.put(methodDeclaration, new QName(getTargetNamespace(methodDeclaration.getDeclaringType()),
                    getOperationName(methodDeclaration)));
        }

        Declaration[] keys = nameMap.keySet().toArray(new Declaration[nameMap.size()]);
        QName[] values = nameMap.values().toArray(new QName[nameMap.size()]);

        for (int i = 0; i < values.length; i++) {
            QName qName = values[i];
            for (int j = i + 1; j < values.length; j++) {
                QName otherQName = values[j];
                if (qName.equals(otherQName)) {
                    printError(keys[i].getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.OPERATION_NAMES_MUST_BE_UNIQUE_ERROR, qName));
                    printError(keys[j].getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.OPERATION_NAMES_MUST_BE_UNIQUE_ERROR, otherQName));
                }
            }
        }
    }

    private String getAttributeValue(Declaration declaration, Class<? extends Annotation> annotation, String attributeName) {
        AnnotationMirror annotationMirror = AnnotationUtils.getAnnotation(declaration, annotation);
        if (annotationMirror != null) {
            return AnnotationUtils.getStringValue(annotationMirror, attributeName);
        }
        return null;
    }

    private void checkWrapperAndFaultBeanNames(Collection<? extends MethodDeclaration> methodDeclarations) {
        AnnotationTypeDeclaration requestWrapperDeclaration = (AnnotationTypeDeclaration) environment
        .getTypeDeclaration(RequestWrapper.class.getName());

        AnnotationTypeDeclaration resposeWrapperDeclaration = (AnnotationTypeDeclaration) environment
        .getTypeDeclaration(ResponseWrapper.class.getName());

        Set<Declaration> methods = new HashSet<Declaration>();
        methods.addAll(environment.getDeclarationsAnnotatedWith(requestWrapperDeclaration));
        methods.addAll(environment.getDeclarationsAnnotatedWith(resposeWrapperDeclaration));

        List<AnnotationValue> classNames = new ArrayList<AnnotationValue>();
        Map<Object, QName> qNames = new HashMap<Object, QName>();

        for (Declaration declaration : methods) {
            if (declaration instanceof MethodDeclaration) {
                AnnotationMirror requestWrapper = AnnotationUtils.getAnnotation(declaration, RequestWrapper.class);
                if (requestWrapper != null) {
                    addClassName(requestWrapper, CLASS_NAME, classNames);
                    addLocalName(requestWrapper, LOCAL_NAME, (MethodDeclaration) declaration, qNames);
                }

                AnnotationMirror responseWrapper = AnnotationUtils.getAnnotation(declaration, ResponseWrapper.class);
                if (responseWrapper != null) {
                    addClassName(responseWrapper, CLASS_NAME, classNames);
                    addLocalName(responseWrapper, LOCAL_NAME, (MethodDeclaration) declaration, qNames);
                }
            }
        }

        Set<ReferenceType> thrownTypes = new HashSet<ReferenceType>();

        for (MethodDeclaration methodDeclaration : methodDeclarations) {
            thrownTypes.addAll(methodDeclaration.getThrownTypes());
        }

        for (ReferenceType referenceType : thrownTypes) {
            if (referenceType instanceof ClassDeclaration) {
                ClassDeclaration classDeclaration = (ClassDeclaration) referenceType;
                AnnotationMirror webFault = AnnotationUtils.getAnnotation(classDeclaration, WebFault.class);
                if (webFault != null) {
                    addClassName(webFault, FAULT_BEAN, classNames);
                }
            }
        }

        for (int i = 0; i < classNames.size(); i++) {
            AnnotationValue className = classNames.get(i);
            for (int j = i + 1; j < classNames.size(); j++) {
                AnnotationValue otherClassName = classNames.get(j);
                if (className.getValue().toString().equalsIgnoreCase(otherClassName.getValue().toString())) {
                    printError(className.getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.WRAPPER_FAULT_BEAN_NAMES_MUST_BE_UNIQUE, className));
                    printError(otherClassName.getPosition(), JAXWSCoreMessages.bind(
                            JAXWSCoreMessages.WRAPPER_FAULT_BEAN_NAMES_MUST_BE_UNIQUE, otherClassName));
                }
            }
        }

        validateQNames(qNames, JAXWSCoreMessages.LOCAL_NAME_ATTRIBUTES_MUST_BE_UNIQUE);
    }

    private void validateQNames(Map<Object, QName> qNames, String errorMessage) {
        Object[] keys =  qNames.keySet().toArray(new Object[qNames.size()]);
        QName[] values = qNames.values().toArray(new QName[qNames.size()]);

        for(int i = 0; i < values.length; i++) {
            QName qName = values[i];
            for(int j = i + 1; j < values.length; j++) {
                QName otherQName = values[j];
                if (qName.equals(otherQName)) {
                    printError(getPosition(keys[i]), JAXWSCoreMessages.bind(errorMessage, qName));
                    printError(getPosition(keys[j]), JAXWSCoreMessages.bind(errorMessage, otherQName));
                }
            }
        }
    }

    private void addClassName(AnnotationMirror annotationMirror, String attributeKey,
            List<AnnotationValue> classNames) {
        AnnotationValue className = AnnotationUtils.getAnnotationValue(annotationMirror, attributeKey);
        if (className != null) {
            classNames.add(className);
        }
    }

    private void addLocalName(AnnotationMirror annotationMirror, String attributeKey,
            MethodDeclaration methodDeclaration, Map<Object, QName> qNames) {
        AnnotationValue localNameValue = AnnotationUtils.getAnnotationValue(annotationMirror, attributeKey);
        if (localNameValue != null) {
            qNames.put(localNameValue, new QName(getTargetNamespace(annotationMirror, methodDeclaration),
                    localNameValue.getValue().toString()));
        }
    }

    private void checkDocumentBareMethods(Collection<? extends MethodDeclaration> methods) {
        List<MethodDeclaration> docBareMethods = new ArrayList<MethodDeclaration>();
        for (MethodDeclaration methodDeclaration : methods) {
            if (hasDocumentBareSOAPBinding(methodDeclaration)) {
                docBareMethods.add(methodDeclaration);
            }
        }

        Map<Object, QName> qNames = new HashMap<Object, QName>();
        for (MethodDeclaration methodDeclaration : docBareMethods) {
            getDocumentBareOperationRequest(methodDeclaration, qNames);
            getDocumentBareOperationResponse(methodDeclaration, qNames);
        }

        validateQNames(qNames, JAXWSCoreMessages.DOC_BARE_METHODS_UNIQUE_XML_ELEMENTS);
    }

    private SourcePosition getPosition(Object value) {
        if (value instanceof AnnotationValue) {
            return ((AnnotationValue) value).getPosition();
        }
        if (value instanceof MethodDeclaration) {
            return ((MethodDeclaration) value).getPosition();
        }
        if (value instanceof ParameterDeclaration) {
            return ((ParameterDeclaration) value).getPosition();
        }
        return null;
    }

    private void getDocumentBareOperationRequest(MethodDeclaration methodDeclaration, Map<Object, QName> qNames) {
        Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
        for (ParameterDeclaration parameterDeclaration : parameters) {
            AnnotationMirror webParam = AnnotationUtils.getAnnotation(parameterDeclaration, WebParam.class);
            if (webParam != null) {
                String mode = getWebParamMode(webParam, parameterDeclaration);
                if (mode.equals(Mode.IN.name()) || mode.equals(Mode.INOUT.name())) {
                    getOperationRequest(webParam, methodDeclaration, parameterDeclaration, qNames);
                }
            } else {
                qNames.put(parameterDeclaration, getOperationRequestDefault(methodDeclaration));
            }
        }
    }

    private void getOperationRequest(AnnotationMirror annotationMirror, MethodDeclaration methodDeclaration,
            ParameterDeclaration parameterDeclaration, Map<Object, QName> qNames) {
        AnnotationValue name = AnnotationUtils.getAnnotationValue(annotationMirror, NAME);
        if (name != null) {
            QName qName = new QName(getTargetNamespace(annotationMirror, methodDeclaration), name.getValue()
                    .toString());
            qNames.put(name, qName);
        } else {
            qNames.put(parameterDeclaration, getOperationRequestDefault(methodDeclaration));
        }
    }

    private QName getOperationRequestDefault(MethodDeclaration methodDeclaration) {
        return new QName(getTargetNamespace(methodDeclaration.getDeclaringType()), methodDeclaration
                .getSimpleName());
    }

    private void getDocumentBareOperationResponse(MethodDeclaration methodDeclaration, Map<Object, QName> qNames) {
        if (!returnsVoid(methodDeclaration)) {
            getOperationResponse(AnnotationUtils.getAnnotation(methodDeclaration, WebResult.class),
                    methodDeclaration, qNames);
        } else {
            Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
            for (ParameterDeclaration parameterDeclaration : parameters) {
                AnnotationMirror webParam = AnnotationUtils.getAnnotation(parameterDeclaration, WebParam.class);
                if (webParam != null) {
                    String mode = getWebParamMode(webParam, parameterDeclaration);
                    if (mode.equals(Mode.OUT.name()) || mode.equals(Mode.INOUT.name()) && !isHeader(webParam)) {
                        getOperationResponse(webParam, methodDeclaration, qNames);
                        break;
                    }
                } else if (getDefaultWebParamMode(parameterDeclaration).equals(Mode.INOUT.name())) {
                    qNames.put(parameterDeclaration, getOperationResponseDefault(methodDeclaration));
                    break;
                }
            }
        }
    }

    private void getOperationResponse(AnnotationMirror annotationMirror, MethodDeclaration methodDeclaration,
            Map<Object, QName> qNames) {
        if (annotationMirror != null) {
            AnnotationValue name = AnnotationUtils.getAnnotationValue(annotationMirror, NAME);
            if (name != null) {
                qNames.put(name, new QName(getTargetNamespace(annotationMirror, methodDeclaration), name
                        .getValue().toString()));
            } else {
                qNames.put(methodDeclaration, getOperationResponseDefault(methodDeclaration));
            }
        } else {
            qNames.put(methodDeclaration, getOperationResponseDefault(methodDeclaration));
        }
    }

    private QName getOperationResponseDefault(MethodDeclaration methodDeclaration) {
        return new QName(getTargetNamespace(methodDeclaration.getDeclaringType()), methodDeclaration
                .getSimpleName()
                + RESPONSE_SUFFIX);
    }

    private boolean isHeader(AnnotationMirror annotationMirror) {
        Boolean header = AnnotationUtils.getBooleanValue(annotationMirror, HEADER);
        if (header != null) {
            return header.booleanValue();
        }
        return false;
    }

    private String getWebParamMode(AnnotationMirror annotationMirror, ParameterDeclaration parameterDeclaration) {
        String mode = AnnotationUtils.getStringValue(annotationMirror, MODE);
        if (mode == null || mode.length() == 0) {
            mode = getDefaultWebParamMode(parameterDeclaration);
        }
        return mode;
    }

    private String getDefaultWebParamMode(ParameterDeclaration parameterDeclaration) {
        TypeMirror typeMirror = environment.getTypeUtils().getErasure(parameterDeclaration.getType());
        if (typeMirror.toString().equals(Holder.class.getCanonicalName())) {
            return Mode.INOUT.name();
        }
        return Mode.IN.name();
    }

    private boolean returnsVoid(MethodDeclaration methodDeclaration) {
        return methodDeclaration.getReturnType().equals(environment.getTypeUtils().getVoidType());
    }

    private void checkMethodParameters(Collection<? extends MethodDeclaration> methodDeclarations) {
        List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();
        for (MethodDeclaration methodDeclaration : methodDeclarations) {
            //Not Doc Bare
            if (!hasDocumentBareSOAPBinding(methodDeclaration)) {
                methods.add(methodDeclaration);
            }
        }

        for (MethodDeclaration methodDeclaration : methods) {
            List<AnnotationValue> names = new ArrayList<AnnotationValue>();
            List<ParameterDeclaration> parameters = (List<ParameterDeclaration>) methodDeclaration.getParameters();
            for (ParameterDeclaration parameterDeclaration : parameters) {
                AnnotationMirror webParam = AnnotationUtils.getAnnotation(parameterDeclaration, WebParam.class);
                if (webParam != null) {
                    AnnotationValue name = AnnotationUtils.getAnnotationValue(webParam, NAME);
                    if (name != null) {
                        names.add(name);
                        testForGeneratedNameClash(name, parameterDeclaration, parameters);
                    }
                }
            }

            for (int i = 0; i < names.size(); i++) {
                AnnotationValue name = names.get(i);
                for (int j = i + 1; j < names.size(); j++) {
                    AnnotationValue otherName = names.get(j);
                    if (name.toString().equals(otherName.toString())) {
                        printError(name.getPosition(), JAXWSCoreMessages.bind(
                                JAXWSCoreMessages.PARAMETER_NAME_CLASH, name.getValue().toString()));
                        printError(otherName.getPosition(), JAXWSCoreMessages.bind(
                                JAXWSCoreMessages.PARAMETER_NAME_CLASH, otherName.getValue().toString()));
                    }
                }
            }
        }
    }

    private void testForGeneratedNameClash(AnnotationValue webParamName, ParameterDeclaration parameter,
            List<ParameterDeclaration> parameters) {
        String name = webParamName.toString();
        Matcher matcher = pattern.matcher(name);
        if (matcher.matches()) {
            int argN = Integer.parseInt(name.substring(3));
            if (argN != parameters.indexOf(parameter)) {
                if (argN < parameters.size()) {
                    ParameterDeclaration parameterN = parameters.get(argN);
                    AnnotationMirror webParamN = AnnotationUtils.getAnnotation(parameterN, WebParam.class);
                    if (webParamN != null) {
                        AnnotationValue webParamNameN = AnnotationUtils.getAnnotationValue(webParamN, NAME);
                        if (webParamNameN == null) {
                            printError(parameterN.getPosition(), JAXWSCoreMessages.bind(
                                    JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                            printError(webParamName.getPosition(), JAXWSCoreMessages.bind(
                                    JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                        } else if (webParamNameN.toString().length() == 0) {
                            printError(webParamNameN.getPosition(), JAXWSCoreMessages.bind(
                                    JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                            printError(webParamName.getPosition(), JAXWSCoreMessages.bind(
                                    JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                        }
                    } else {
                        printError(parameterN.getPosition(), JAXWSCoreMessages.bind(
                                JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                        printError(webParamName.getPosition(), JAXWSCoreMessages.bind(
                                JAXWSCoreMessages.GENERATED_PARAMETER_NAME_CLASH, name));
                    }
                }
            }
        }
    }

    private String getTargetNamespace(TypeDeclaration typeDeclaration) {
        String targetNamespace = getAttributeValue(typeDeclaration, WebService.class, TARGET_NAMESPACE);
        if (targetNamespace != null) {
            return targetNamespace;
        }

        return JDTUtils.getTargetNamespaceFromPackageName(typeDeclaration.getPackage().getQualifiedName());
    }

    private String getTargetNamespace(AnnotationMirror annotationMirror, MethodDeclaration methodDeclaration) {
        String targetNamespace = AnnotationUtils.getStringValue(annotationMirror, TARGET_NAMESPACE);
        if (targetNamespace == null) {
            targetNamespace = getTargetNamespace(methodDeclaration.getDeclaringType());
        }
        return targetNamespace;
    }

    private String getOperationName(MethodDeclaration methodDeclaration) {
        String operationName = getAttributeValue(methodDeclaration, WebMethod.class, OPERATION_NAME);
        if (operationName != null) {
            return operationName;
        }
        return methodDeclaration.getSimpleName();
    }

    private boolean hasDocumentBareSOAPBinding(Declaration declaration) {
        AnnotationMirror soapBinding = AnnotationUtils.getAnnotation(declaration, SOAPBinding.class);
        if (soapBinding != null) {
            return JAXWSUtils.isDocumentBare(soapBinding);
        }
        if (declaration instanceof MethodDeclaration) {
            MethodDeclaration methodDeclaration = (MethodDeclaration) declaration;
            return hasDocumentBareSOAPBinding(methodDeclaration.getDeclaringType());
        }

        return false;
    }
}
