package org.apache.tiles.autotag.core;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.tiles.autotag.core.runtime.ModelBody;
import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
import org.apache.tiles.autotag.model.TemplateClass;
import org.apache.tiles.autotag.model.TemplateMethod;
import org.apache.tiles.autotag.model.TemplateParameter;
import org.apache.tiles.autotag.model.TemplateSuite;
import org.apache.tiles.autotag.model.TemplateSuiteFactory;
import org.apache.tiles.request.Request;

import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.Annotation;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.Type;

public class QDoxTemplateSuiteFactory implements TemplateSuiteFactory {

    private static final String TEMPLATE_SUFFIX = "Model";

    private JavaDocBuilder builder;

    private String suiteName;

    private String suiteDocumentation;

    public QDoxTemplateSuiteFactory(File... sourceFiles) {
        builder = new JavaDocBuilder();
        try {
            for (File file : sourceFiles) {
                builder.addSource(file);
            }
        } catch (IOException e) {
            throw new ClassParseException(
                    "I/O Exception when adding source files", e);
        }
    }

    public QDoxTemplateSuiteFactory(URL... urls) {
        builder = new JavaDocBuilder();
        try {
            for (URL url : urls) {
                builder.addSource(url);
            }
        } catch (IOException e) {
            throw new ClassParseException(
                    "I/O Exception when adding source files", e);
        }
    }

    public void setSuiteName(String suiteName) {
        this.suiteName = suiteName;
    }

    public void setSuiteDocumentation(String suiteDocumentation) {
        this.suiteDocumentation = suiteDocumentation;
    }

    @Override
    public TemplateSuite createTemplateSuite() {
        List<TemplateClass> classes = new ArrayList<TemplateClass>();
        for (JavaClass clazz : builder.getClasses()) {
            String tagClassPrefix = getTagClassPrefix(clazz);
            if (tagClassPrefix != null) {
                String tagName = tagClassPrefix.substring(0, 1).toLowerCase()
                        + tagClassPrefix.substring(1);
                TemplateMethod executeMethod = null;
                for (JavaMethod method : clazz.getMethods()) {
                    if (isFeasible(method)) {
                        executeMethod = createMethod(method);
                    }
                }
                if (executeMethod != null) {
                    TemplateClass templateClass = new TemplateClass(clazz
                            .getFullyQualifiedName(), tagName, tagClassPrefix,
                            executeMethod);
                    templateClass.setDocumentation(clazz.getComment());
                    classes.add(templateClass);
                }
            }
        }
        return new TemplateSuite(suiteName, suiteDocumentation, classes);
    }

    private String getTagClassPrefix(JavaClass clazz) {
        String tagName;
        String simpleClassName = clazz.getName();
        if (simpleClassName.endsWith(TEMPLATE_SUFFIX)
                && simpleClassName.length() > TEMPLATE_SUFFIX.length()) {
            tagName = simpleClassName.substring(0, 1).toUpperCase()
                    + simpleClassName.substring(1, simpleClassName.length()
                            - TEMPLATE_SUFFIX.length());
        } else {
            tagName = null;
        }
        return tagName;
    }

    private TemplateMethod createMethod(JavaMethod method) {
        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
        for (JavaParameter parameter : method.getParameters()) {
            String exportedName = parameter.getName();
            boolean required = false;
            String defaultValue = null;
            Annotation[] annotations = parameter.getAnnotations();
            if (annotations != null && annotations.length > 0) {
                boolean found = false;
                for (int i = 0; i < annotations.length && !found; i++) {
                    if (Parameter.class.getName().equals(annotations[i].getType().getFullyQualifiedName())) {
                        found = true;
                        String candidateName = (String) annotations[i].getNamedParameter("name");
                        if (candidateName != null && candidateName.length() > 2) {
                            exportedName = candidateName.substring(1, candidateName.length() - 1);
                        }
                        required = "true".equals(annotations[i].getNamedParameter("required"));
                        candidateName = (String) annotations[i].getNamedParameter("defaultValue");
                        if (candidateName != null && candidateName.length() > 2) {
                            defaultValue = candidateName.substring(1, candidateName.length() - 1);
                        }
                    }
                }
            }
            TemplateParameter templateParameter = new TemplateParameter(
                    parameter.getName(), exportedName, parameter.getType()
                            .getFullyQualifiedName(), defaultValue, required);
            params.add(templateParameter);
        }
        TemplateMethod templateMethod = new TemplateMethod(method.getName(),
                params);
        templateMethod.setDocumentation(method.getComment());
        DocletTag[] tags = method.getTagsByName("param");
        for (DocletTag tag : tags) {
            String[] tagParams = tag.getParameters();
            if (tagParams.length > 0) {
                TemplateParameter templateParameter = templateMethod
                        .getParameterByName(tagParams[0]);
                if (templateParameter != null) {
                    String tagValue = tag.getValue();
                    int pos = tagValue.indexOf(" ");
                    templateParameter.setDocumentation(tagValue.substring(pos)
                            .trim());
                }
            }
        }
        return templateMethod;
    }

    private boolean isFeasible(JavaMethod method) {
        Type returns = method.getReturns();
        if ("execute".equals(method.getName()) && returns != null
                && "void".equals(returns.getFullyQualifiedName())
                && method.isPublic() && !method.isStatic()
                && !method.isAbstract() && !method.isConstructor()) {
            JavaParameter[] params = method.getParameters();
            if (params.length > 0) {
                JavaParameter param = params[params.length - 1];
                if (Request.class.getName().equals(
                        param.getType().getFullyQualifiedName())) {
                    return true;
                }
            }
            if (params.length >= 2) {
                JavaParameter param1 = params[params.length - 2];
                JavaParameter param2 = params[params.length - 1];
                if (Request.class.getName().equals(
                        param1.getType().getFullyQualifiedName())
                        && ModelBody.class.getName().equals(
                                param2.getType().getFullyQualifiedName())) {
                    return true;
                }
            }
        }
        return false;
    }
}
