/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.maven2.java2wsdl;

import org.apache.axis2.description.java2wsdl.Java2WSDLConstants;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.ws.java2wsdl.Java2WSDLCodegenEngine;
import org.apache.ws.java2wsdl.utils.Java2WSDLCommandLineOption;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;


/**
 * Takes a Java class as input and converts it into an equivalent
 * WSDL file.
 * 
 * @goal java2wsdl
 * @phase process-classes
 * @requiresDependencyResolution compile
 * @threadSafe
 */
public class Java2WSDLMojo extends AbstractMojo {
    public static final String OPEN_BRACKET = "[";
    public static final String CLOSE_BRACKET = "]";
    public static final String COMMA = ",";

    /**
     * The maven project.
     * @parameter property="project"
     * @read-only
     * @required
     */
    private MavenProject project;

    /**
     * Fully qualified name of the class, which is being inspected.
     * @parameter property="axis2.java2wsdl.className"
     * @required
     */
    private String className;

    /**
     * Target namespace of the generated WSDL.
     * @parameter property="axis2.java2wsdl.targetNamespace"
     */
    private String targetNamespace;

    /**
     * The namespace prefix, which is being used for the WSDL's
     * target namespace.
     * @parameter property="axis2.java2wsdl.targetNamespacePrefix"
     */
    private String targetNamespacePrefix;

    /**
     * The generated schemas target namespace.
     * @parameter property="axis2.java2wsdl.schemaTargetNamespace"
     */
    private String schemaTargetNamespace;

    /**
     * The generated schemas target namespace prefix.
     * @parameter property="axis2.java2wsdl.schemaTargetNamespacePrefix"
     */
    private String schemaTargetNamespacePrefix;

    /**
     * Name of the generated service.
     * @parameter property="axis2.java2wsdl.serviceName"
     */
    private String serviceName;

    /**
     * Name of the service file, which is being generated.
     * @parameter property="axis2.java2wsdl.outputFileName" default-value="${project.build.directory}/generated-resources/service.wsdl"
     */
    private String outputFileName;

    /**
     * Style for the wsdl
     * @parameter property="axis2.java2wsdl.style"
     */
    private String style;

    /**
     * Use for the wsdl
     * @parameter property="axis2.java2wsdl.use"
     */
    private String use;

    /**
     * Version for the wsdl
     * @parameter property="axis2.java2wsdl.wsdlVersion"
     */
    private String wsdlVersion;

    /**
     * Namespace Generator
     * @parameter property="axis2.java2wsdl.nsGenClassName"
     */
    private String nsGenClassName;

    /**
     * Schema Generator
     * @parameter property="axis2.java2wsdl.schemaGenClassName"
     */
    private String schemaGenClassName;

    /**
     * Location URI in the wsdl
     * @parameter property="axis2.java2wsdl.locationUri"
     */
    private String locationUri;

    /**
     * attrFormDefault setting for the schema
     * @parameter property="axis2.java2wsdl.attrFormDefault"
     */
    private String attrFormDefault;

    /**
     * elementFormDefault setting for the schema
     * @parameter property="axis2.java2wsdl.elementFormDefault"
     */
    private String elementFormDefault;

    /**
     * Switch on the Doc/Lit/Bare style schema
     * @parameter property="axis2.java2wsdl.docLitBare"
     */
    private String docLitBare;

    /**
     * Additional classes for which we need to generate schema
     * @parameter property="axis2.java2wsdl.extraClasses"
     */
    private String[] extraClasses;

    /**
     * Specify namespaces explicitly for packages
     * @parameter property="axis2.java2wsdl.package2Namespace"
     */
    private Properties package2Namespace;

    private void addToOptionMap(Map map, String option, String value) {
        addToOptionMap(map, option, new String[]{value});
    }

    private void addToOptionMap(Map map, String option, String[] value) {
        if (value != null) {
            map.put(option,
                    new Java2WSDLCommandLineOption(option, value));
        }
    }

    private void addToOptionMap(Map map, String option, ArrayList values) {
        if (values != null && !values.isEmpty()) {
            map.put(option,
                    new Java2WSDLCommandLineOption(option, values));
        }
    }

    /**
     * Fills the option map. This map is passed onto
     * the code generation API to generate the code.
     */
    private Map fillOptionMap() throws MojoFailureException {
        Map optionMap = new HashMap();

        if (className == null) {
            throw new MojoFailureException("You must specify a classname");
        }
        addToOptionMap( optionMap,
                        Java2WSDLConstants.CLASSNAME_OPTION,
                        className);
        addToOptionMap( optionMap,
                        Java2WSDLConstants.TARGET_NAMESPACE_OPTION,
                        targetNamespace);
        addToOptionMap( optionMap,
                        Java2WSDLConstants.TARGET_NAMESPACE_PREFIX_OPTION,
                        targetNamespacePrefix);
        addToOptionMap( optionMap,
                        Java2WSDLConstants.SCHEMA_TARGET_NAMESPACE_OPTION,
                        schemaTargetNamespace);
        addToOptionMap( optionMap,
                        Java2WSDLConstants.SCHEMA_TARGET_NAMESPACE_PREFIX_OPTION,
                        schemaTargetNamespacePrefix);
        addToOptionMap( optionMap,
                        Java2WSDLConstants.SERVICE_NAME_OPTION,
                        serviceName);
        File outputFile = new File(outputFileName);
        if(!outputFile.isAbsolute()){
            outputFile = new File(project.getBasedir(), outputFileName);
        }
        File dir = outputFile.getParentFile();
        if (!dir.isDirectory()) {
            dir.mkdirs();
        }
        addToOptionMap( optionMap,
                        Java2WSDLConstants.OUTPUT_LOCATION_OPTION,
                        dir.getPath() );
        addToOptionMap( optionMap,
                        Java2WSDLConstants.OUTPUT_FILENAME_OPTION,
                        outputFile.getName() );

        Artifact projectArtifact = project.getArtifact();
        Set<Artifact> artifacts = project.getArtifacts();
        String[] artifactFileNames = new String[artifacts.size() + (projectArtifact == null ? 0 : 1)];
        int j = 0;
        for (Artifact artifact : artifacts) {
            artifactFileNames[j++] = artifact.getFile().getAbsolutePath();
        }
        if(projectArtifact != null) {
            File file = projectArtifact.getFile();
            if(file != null){
                artifactFileNames[j] = file.getAbsolutePath();
            }
        }

        addToOptionMap( optionMap,
                        Java2WSDLConstants.CLASSPATH_OPTION,
                        artifactFileNames);

        if (style != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.STYLE_OPTION,
                    style);
        }

        if (use != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.USE_OPTION,
                    use);
        }

        if (wsdlVersion != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.WSDL_VERSION_OPTION,
                    wsdlVersion);
        }

        if (docLitBare != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.DOC_LIT_BARE,
                    docLitBare);
        }

        if (locationUri != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.LOCATION_OPTION,
                    locationUri);
        }

        if (nsGenClassName != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.NAMESPACE_GENERATOR_OPTION,
                    nsGenClassName);
        }

        if (schemaGenClassName != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.SCHEMA_GENERATOR_OPTION,
                    schemaGenClassName);
        }

        if (attrFormDefault != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.ATTR_FORM_DEFAULT_OPTION,
                    attrFormDefault);
        }

        if (elementFormDefault != null) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.ELEMENT_FORM_DEFAULT_OPTION,
                    elementFormDefault);
        }

        if (extraClasses != null && extraClasses.length > 0) {
            addToOptionMap(optionMap,
                    Java2WSDLConstants.EXTRA_CLASSES_DEFAULT_OPTION,
                    extraClasses);
        }

        ArrayList list = new ArrayList();
        if(package2Namespace != null){
            Iterator iterator = package2Namespace.entrySet().iterator();
    
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                String packageName = (String) entry.getKey();
                String namespace = (String) entry.getValue();
                list.add(OPEN_BRACKET +
                        packageName +
                        COMMA +
                        namespace +
                        CLOSE_BRACKET);
            }
        }
        addToOptionMap(optionMap,
                Java2WSDLConstants.JAVA_PKG_2_NSMAP_OPTION,
                list);

        return optionMap;
    }

    public void execute() throws MojoExecutionException, MojoFailureException {
        Map commandLineOptions = fillOptionMap();
        try {
            new Java2WSDLCodegenEngine(commandLineOptions).generate();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }
}
