/*******************************************************************************
 * 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.ui.views;

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

import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.jaxws.ui.JAXWSUIPlugin;
import org.eclipse.swt.graphics.Image;

/**
 * 
 * @author sclarke
 *
 */
public class AnnotationsValuesColumnLabelProvider extends ColumnLabelProvider {
    private TreeViewer annotationTreeViewer;
    private Image true_image;
    private Image false_image;
    
    public AnnotationsValuesColumnLabelProvider(TreeViewer annotationTreeViewer) {
        this.annotationTreeViewer = annotationTreeViewer;
        true_image = JAXWSUIPlugin.imageDescriptorFromPlugin(JAXWSUIPlugin.PLUGIN_ID, "icons/obj16/true.gif") //$NON-NLS-1$
                .createImage();
        false_image = JAXWSUIPlugin.imageDescriptorFromPlugin(JAXWSUIPlugin.PLUGIN_ID, "icons/obj16/false.gif") //$NON-NLS-1$
                .createImage();
    }
    
    @Override
    public String getText(Object element) {
        String text = ""; //$NON-NLS-1$
        if (element instanceof Method) {
            text =  getTextForMethod((Method)element);
        }
        return text;
    }
    
    private String getTextForMethod(Method method) {
        String text = ""; //$NON-NLS-1$
        if (annotationTreeViewer.getInput() instanceof IAnnotatable) {
            text = getTextForMethod(method, (IAnnotatable) annotationTreeViewer.getInput());
        } else if (annotationTreeViewer.getInput() instanceof SingleVariableDeclaration) {
            text = getTextForMethod(method, (SingleVariableDeclaration)annotationTreeViewer.getInput());
        }
        return text;
    }

    private String getTextForMethod(Method method, IAnnotatable annotatedElement) {
        Class<?> returnType = method.getReturnType();
        try {
            IAnnotation[] annotations = annotatedElement.getAnnotations();
            for (IAnnotation annotation : annotations) {
                Class<?> declaringClass = method.getDeclaringClass();
                if (annotation.getElementName().equals(declaringClass.getSimpleName())
                        || annotation.getElementName().equals(declaringClass.getCanonicalName())) {
                    IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs();
                    for (IMemberValuePair memberValuePair : memberValuePairs) {
                        if (memberValuePair.getValue() == null) {
                            break;
                        }
                        if (memberValuePair.getMemberName().equals(method.getName())) {
                            if (returnType.equals(String.class)) {
                                return memberValuePair.getValue().toString();
                            }
                            
                            if (returnType.equals(Class.class)) {
                                return memberValuePair.getValue().toString() + ".class";  //$NON-NLS-1$
                            }
                            if (returnType.isPrimitive() && (returnType.equals(Byte.TYPE) 
                                    || returnType.equals(Short.TYPE) 
                                    || returnType.equals(Integer.TYPE) || returnType.equals(Long.TYPE)
                                    || returnType.equals(Float.TYPE) 
                                    || returnType.equals(Double.TYPE))) {
                                return memberValuePair.getValue().toString();
                            }
                            
                            if (returnType.isArray()) {
                                Object[] values = (Object[])memberValuePair.getValue();
                                if (values != null && values.length > 0) {
                                    return "[]{...}"; //$NON-NLS-1$
                                } else {
                                    return "[]{}"; //$NON-NLS-1$
                                }
                            }
                            
                            if (returnType.isEnum()) {
                                String enumValue = memberValuePair.getValue().toString();
                                return enumValue.substring(enumValue.lastIndexOf(".") + 1); //$NON-NLS-1$
                            }
                        }
                    }
                }
            }
        } catch (JavaModelException jme) {
            JAXWSUIPlugin.log(jme.getStatus());
        }
        return ""; //$NON-NLS-1$
    }

    @SuppressWarnings("unchecked")
    private String getTextForMethod(Method method, SingleVariableDeclaration singleVariableDeclaration) {
        Class<?> returnType = method.getReturnType();
        List<IExtendedModifier> modifiers = singleVariableDeclaration.modifiers();
        for (IExtendedModifier extendedModifier : modifiers) {
            if (extendedModifier instanceof NormalAnnotation) {
                NormalAnnotation normalAnnotation = (NormalAnnotation) extendedModifier;
                String annotationName = AnnotationUtils.getAnnotationName(normalAnnotation);
                Class<?> declaringClass = method.getDeclaringClass();
                if (annotationName.equals(declaringClass.getSimpleName()) || 
                        annotationName.equals(declaringClass.getCanonicalName())) {
                    List<MemberValuePair> memberValuePairs = normalAnnotation.values();
                    for (MemberValuePair memberValuePair : memberValuePairs) {
                        if (memberValuePair.getName().toString().equals(method.getName())) {
                            if (returnType.equals(String.class)) {
                                StringLiteral stringLiteral = (StringLiteral)memberValuePair.getValue();
                                return stringLiteral.getLiteralValue();
                            }

                            if (returnType.isPrimitive() && (returnType.equals(Byte.TYPE) 
                                    || returnType.equals(Short.TYPE) 
                                    || returnType.equals(Integer.TYPE) || returnType.equals(Long.TYPE)
                                    || returnType.equals(Float.TYPE) 
                                    || returnType.equals(Double.TYPE))) {
                                return memberValuePair.getValue().toString();
                            }

                            if (returnType.isEnum()) {
                                String enumValue = memberValuePair.getValue().toString();
                                return enumValue.substring(enumValue.lastIndexOf(".") + 1); //$NON-NLS-1$
                            }
                        }
                    }
                }
            }
        }
        return ""; //$NON-NLS-1$
    }
    
    @Override
    public Image getImage(Object element) {
        try {
            if (element instanceof Class) {
                return getImageForClass((Class<?>) element);
            }
            if (element instanceof Method) {
                return getImageForMethod((Method) element);
            }
        } catch (JavaModelException jme) {
            JAXWSUIPlugin.log(jme.getStatus());
        }
        return null;
    }
        
    private Image getImageForClass(Class<?> aClass) throws JavaModelException {
        if (annotationTreeViewer.getInput() instanceof IAnnotatable) {
            return getImageForClass(aClass, (IAnnotatable) annotationTreeViewer.getInput());
        }
        
        if (annotationTreeViewer.getInput() instanceof SingleVariableDeclaration) {
            return getImageForClass(aClass, (SingleVariableDeclaration)annotationTreeViewer.getInput());
        }
        return false_image;        
    }
    
    private Image getImageForClass(Class<?> aClass, IAnnotatable annotatedElement) throws JavaModelException {
        IAnnotation[] annotations = annotatedElement.getAnnotations();
        for (IAnnotation annotation : annotations) {
            String annotationName = annotation.getElementName();
            if (AnnotationUtils.isAnnotationPresent((IJavaElement)annotatedElement, annotationName) && 
                    (annotationName.equals(aClass.getSimpleName()) || 
                    annotationName.equals(aClass.getCanonicalName()))) {
                return true_image;
            }
        }
        return false_image;
    }
    
    @SuppressWarnings("unchecked")
    private Image getImageForClass(Class<?> aClass, SingleVariableDeclaration parameter) {
        List<IExtendedModifier> modifiers = parameter.modifiers();
        for (IExtendedModifier extendedModifier : modifiers) {
            if (extendedModifier instanceof Annotation) {
                Annotation annotation = (Annotation) extendedModifier;
                String annotationName = AnnotationUtils.getAnnotationName(annotation);
                if (AnnotationUtils.isAnnotationPresent(parameter, annotation)
                        && (annotationName.equals(aClass.getSimpleName())
                        || annotationName.equals(aClass.getCanonicalName()))) {
                    return true_image;
                }
            }
        }
        return false_image;
    }
    
    private Image getImageForMethod(Method method) throws JavaModelException {
        Class<?> returnType = method.getReturnType();
        if (returnType.equals(Boolean.TYPE)) {
            if (annotationTreeViewer.getInput() instanceof IAnnotatable) {
                return getImageForMethod(method, (IAnnotatable) annotationTreeViewer.getInput());
            }
            if (annotationTreeViewer.getInput() instanceof SingleVariableDeclaration) {
                return getImageForMethod(method, (SingleVariableDeclaration)annotationTreeViewer.getInput());
            }
        }
        return null;
    }

    private Image getImageForMethod(Method method, IAnnotatable annotatedElement) throws JavaModelException {
        IAnnotation[] annotations = annotatedElement.getAnnotations();
        for (IAnnotation annotation : annotations) {
            String annotationName = annotation.getElementName();
            Class<?> declaringClass = method.getDeclaringClass();
            if (annotationName.equals(declaringClass.getSimpleName())
                    || annotationName.equals(declaringClass.getCanonicalName())) {
                IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs();
                for (IMemberValuePair memberValuePair : memberValuePairs) {
                    if (memberValuePair.getMemberName().equals(method.getName())) {
                        if (Boolean.parseBoolean(memberValuePair.getValue().toString())) {
                            return true_image;
                        }
                    }
                }
            }
        }
        return false_image;
    }
    
    @SuppressWarnings("unchecked")
    private Image getImageForMethod(Method method, SingleVariableDeclaration singleVariableDeclaration) 
            throws JavaModelException {
        List<IExtendedModifier> modifiers = singleVariableDeclaration.modifiers();
        for (IExtendedModifier extendedModifier : modifiers) {
            if (extendedModifier instanceof NormalAnnotation) {
                NormalAnnotation annotation = (NormalAnnotation) extendedModifier;
                String annotationName = AnnotationUtils.getAnnotationName(annotation);
                Class<?> declaringClass = method.getDeclaringClass();
                if (annotationName.equals(declaringClass.getSimpleName())
                        || annotationName.equals(declaringClass.getCanonicalName())) {
                    List<MemberValuePair> memberValuePairs = annotation.values();
                    for (MemberValuePair memberValuePair : memberValuePairs) {
                        if (memberValuePair.getName().toString().equals(method.getName())) {
                            BooleanLiteral booleanLiteral = (BooleanLiteral)memberValuePair.getValue();
                            if (booleanLiteral.booleanValue()) {
                                return true_image;
                            }
                        }
                    }
                }
            }
        }
        return false_image;
    }

    @Override
    public void dispose() {
        super.dispose();
        true_image.dispose();
        false_image.dispose();
    }
}
