/*******************************************************************************
 * Copyright (c) 2008 IONA Technologies PLC
 * 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:
 * IONA Technologies PLC - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.core.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSDataModel;
import org.eclipse.jst.ws.internal.cxf.core.model.WSDL2JavaDataModel;

/**
 * @author sclarke
 */
@SuppressWarnings("restriction")
public final class CommandLineUtils {
    // Java2WSDL
    private static String OUT_FILE = "-o"; //$NON-NLS-1$
    private static String RESOURCE_DIR = "-d"; //$NON-NLS-1$
    private static String SOURCE_DIR = "-s"; //$NON-NLS-1$
    private static String CLASS_DIR = "-classdir"; //$NON-NLS-1$
    private static String J2W_CLASSPATH = "-cp"; //$NON-NLS-1$
    private static String INC_SOAP12 = "-soap12"; //$NON-NLS-1$
    private static String TARGET_NAMESPACE = "-t"; //$NON-NLS-1$
    private static String J2W_SERVICE_NAME = "-servicename"; //$NON-NLS-1$
    private static String PORT_NAME = "-portname"; //$NON-NLS-1$
    private static String GEN_XSD_IMPORTS = "-createxsdimports"; //$NON-NLS-1$
    private static String VERBOSE = "-verbose"; //$NON-NLS-1$

    // Java2WS
    private static String J2W_FRONTEND = "-frontend"; //$NON-NLS-1$
    private static String J2W_DATABINDING = "-databinding"; //$NON-NLS-1$
    private static String BEAN_PATH = "-beans"; //$NON-NLS-1$
    private static String GEN_WSDL = "-wsdl"; //$NON-NLS-1$
    private static String GEN_CLIENT = "-client"; //$NON-NLS-1$
    private static String GEN_SERVER = "-server"; //$NON-NLS-1$
    private static String GEN_WRAPPER_FAULT = "-wrapperbean"; //$NON-NLS-1$

    private static String W2J_PACKAGE_NAME = "-p"; //$NON-NLS-1$
    private static String W2J_BINDING_NAME = "-b"; //$NON-NLS-1$

    private static String W2J_FRONTEND = "-fe"; //$NON-NLS-1$
    private static String W2J_DATABINDING = "-db"; //$NON-NLS-1$
    private static String W2J_WSDL_VERSION = "-wv"; //$NON-NLS-1$
    private static String W2J_SERVICE_NAME = "-sn"; //$NON-NLS-1$
    private static String W2J_CATALOG = "-catalog"; //$NON-NLS-1$
    private static String W2J_COMPILE = "-compile"; //$NON-NLS-1$
    private static String W2J_GEN_IMPL = "-impl"; //$NON-NLS-1$
    private static String W2J_GEN_ALL = "-all"; //$NON-NLS-1$
    private static String W2J_NO_OVERWRITE = "-keep"; //$NON-NLS-1$
    private static String W2J_DEFAULT_VALUES = "-defaultValues"; //$NON-NLS-1$
    private static String W2J_EXCLUDE_NAMESPACE = "-nexclude"; //$NON-NLS-1$
    private static String W2J_EXT_SOAP_HEADER = "-exsh"; //$NON-NLS-1$
    private static String W2J_DEFAULT_NAMESPACE = "-dns"; //$NON-NLS-1$
    private static String W2J_DEFAULT_EXCLUDE_NS = "-dex"; //$NON-NLS-1$
    private static String W2J_WSDL_LOCATION = "-wsdlLocation"; //$NON-NLS-1$
    private static String W2J_XJC_ARGS = "-xjc"; //$NON-NLS-1$
    private static String W2J_NO_ADDRESS_BINDING = "-noAddressBinding"; //$NON-NLS-1$
    private static String W2J_VALIDATE_WSDL = "-validate"; //$NON-NLS-1$

    // XJC
    private static final String XJC_DV_ARG = "-Xdv"; //$NON-NLS-1$
    private static final String XJC_TS_ARG = "-Xts"; //$NON-NLS-1$
    private static final String XJC_TS_MULTI_ARG = "-Xts:style:multiline"; //$NON-NLS-1$
    private static final String XJC_TS_SIMPLE = "-Xts:style:simple"; //$NON-NLS-1$
    private static final String XJC_LOCATOR_ARG = "-Xlocator"; //$NON-NLS-1$
    private static final String XJC_SYNC_METHODS_ARG = "-Xsync-methods"; //$NON-NLS-1$
    private static final String XJC_MARK_GENERATED_ARG = "-mark-generated"; //$NON-NLS-1$
    private static final String XJC_EPISODE_FILE_ARG = "-episode"; //$NON-NLS-1$

    private CommandLineUtils() {
    }
    
    public static String[] getJava2WSProgramArguments(Java2WSDataModel model) {
        List<String> progArgs = new ArrayList<String>();

        IProject project = ResourceUtils.getWorkspaceRoot().getProject(model.getProjectName());
        if (project != null && project.exists() && JDTUtils.isJavaProject(project)) {
            String className = model.getJavaStartingPoint();
            if (model.isUseServiceEndpointInterface() && model.getFullyQualifiedJavaClassName() != null) {
                className = model.getFullyQualifiedJavaClassName();
            }
            // Add all the earlier wsdl2java tool options
            progArgs.addAll(Arrays.asList(CommandLineUtils.getStandardJava2WSDLProgramArguments(model)));

            if (model.getCxfRuntimeVersion().compareTo(CXFCorePlugin.CXF_VERSION_2_1) >= 0) {
                progArgs.add(J2W_FRONTEND);
                progArgs.add(model.getFrontend().getLiteral());

                progArgs.add(J2W_DATABINDING);
                progArgs.add(model.getDatabinding().getLiteral());

                // progArgs.add(BEAN_PATH);
                // progArgs.add("BEAN_PATH");

                if (model.isGenerateWSDL()) {
                    progArgs.add(GEN_WSDL);
                } else {
                    progArgs.remove(OUT_FILE);
                    progArgs.remove(model.getWsdlFileName());
                }

                if (model.isGenerateClient()) {
                    progArgs.add(GEN_CLIENT);
                }
                
                if (model.isGenerateServer()) {
                    progArgs.add(GEN_SERVER);
                }

                if (model.isGenerateWrapperFaultBeans()) {
                    progArgs.add(GEN_WRAPPER_FAULT);
                }
            }

            progArgs.add(className);
        }
        return (String[]) progArgs.toArray(new String[progArgs.size()]);
    }
    
    private static String[] getStandardJava2WSDLProgramArguments(Java2WSDataModel model) {
        String projectName = model.getProjectName();
        List<String> progArgs = new ArrayList<String>();
        progArgs.add(J2W_CLASSPATH);
        progArgs.add(JDTUtils.getJavaProjectOutputDirectoryPath(projectName));

        progArgs.add(SOURCE_DIR);
        progArgs.add(FileUtils.getTmpFolder(projectName) + "/src"); //$NON-NLS-1$

        progArgs.add(RESOURCE_DIR);
        progArgs.add(FileUtils.getTmpFolder(projectName) + "/wsdl"); //$NON-NLS-1$

        progArgs.add(CLASS_DIR);
        progArgs.add(JDTUtils.getJavaProjectOutputDirectoryPath(projectName));

        progArgs.add(OUT_FILE);
        progArgs.add(((Java2WSDataModel) model).getWsdlFileName());

        if (model.isSoap12Binding()) {
            progArgs.add(INC_SOAP12);
        }
        if (model.isGenerateXSDImports()) {
            progArgs.add(GEN_XSD_IMPORTS);
        }

        if (model.isVerbose()) {
            progArgs.add(VERBOSE);
        }
        
        return (String[]) progArgs.toArray(new String[progArgs.size()]);
    }

    public static String[] getWSDL2JavaProgramArguments(WSDL2JavaDataModel model) {
        String projectName = model.getProjectName();
        List<String> progArgs = new ArrayList<String>();

        IProject project = ResourceUtils.getWorkspaceRoot().getProject(projectName);
        if (project != null && project.exists() && JDTUtils.isJavaProject(project)) {
            // Add Standard args
            progArgs.addAll(Arrays.asList(CommandLineUtils.getStandardWSDL2JavaProgramArguments(model,
                    projectName)));
            
            String serviceName = model.getServiceName();
            if (serviceName != null && serviceName.length() > 0) {
                progArgs.add(W2J_SERVICE_NAME);
                progArgs.add(serviceName);
            }
            
            if (model.getCxfRuntimeVersion().compareTo(CXFCorePlugin.CXF_VERSION_2_1) >= 0) {
                progArgs.add(W2J_FRONTEND);
                progArgs.add(model.getFrontend().getLiteral());

                progArgs.add(W2J_DATABINDING);
                progArgs.add(model.getDatabinding().getLiteral());

                progArgs.add(W2J_WSDL_VERSION);
                progArgs.add(model.getWsdlVersion());

                if (model.isUseDefaultValues()) {
                    progArgs.add(W2J_DEFAULT_VALUES);
                }
                
                if (model.isNoAddressBinding()) {
                    progArgs.add(W2J_NO_ADDRESS_BINDING);
                }
            }

            progArgs.add(model.getWsdlURL().toExternalForm());
        }
        return (String[]) progArgs.toArray(new String[progArgs.size()]);
    }

    public static String[] getWSDL2JavaGenerateClientArguments(WSDL2JavaDataModel model) {
        String projectName = model.getProjectName();
        List<String> progArgs = new ArrayList<String>();

        IProject project = ResourceUtils.getWorkspaceRoot().getProject(projectName);
        if (project != null && project.exists() && JDTUtils.isJavaProject(project)) {
            // Add Standard args
            progArgs.addAll(Arrays.asList(CommandLineUtils.getStandardWSDL2JavaProgramArguments(model,
                    projectName)));
            
            progArgs.add(GEN_CLIENT);
            progArgs.add(model.getWsdlURL().toExternalForm());
        }
        return (String[]) progArgs.toArray(new String[progArgs.size()]);
    }
    
    public static String[] getStandardWSDL2JavaProgramArguments(WSDL2JavaDataModel model, String projectName) {
        List<String> progArgs = new ArrayList<String>();
        progArgs.add(RESOURCE_DIR);
        progArgs.add(FileUtils.getTmpFolder(projectName) + "/src"); //$NON-NLS-1$

        progArgs.add(CLASS_DIR);
        progArgs.add(JDTUtils.getJavaProjectOutputDirectoryPath(projectName));

        Map<String, String> includedNamespaces = model.getIncludedNamespaces();
        if (includedNamespaces != null && model.getIncludedNamespaces().size() > 0) {
            Set<Map.Entry<String, String>> includedNamespacesEntrySet = includedNamespaces.entrySet();
            for (Map.Entry<String, String> entry : includedNamespacesEntrySet) {
                progArgs.add(W2J_PACKAGE_NAME);
                String wsdlNamespace = entry.getKey();
                String packageName = entry.getValue();
                progArgs.add(wsdlNamespace + "=" + packageName); //$NON-NLS-1$
            }
        }

        List<String> bindingFiles = model.getBindingFiles();
        if (!bindingFiles.isEmpty()) {
            for (String bindingFile : bindingFiles) {
                progArgs.add(W2J_BINDING_NAME);
                progArgs.add(bindingFile);
            }
        }
        
        if (model.isGenerateServer()) {
            progArgs.add(GEN_SERVER);
        }

        if (model.isGenerateImplementation()) {
            progArgs.add(W2J_GEN_IMPL);
        }

        if(model.isValidate()) {
            progArgs.add(W2J_VALIDATE_WSDL);
        }
        
        progArgs.add(W2J_EXT_SOAP_HEADER);
        progArgs.add(Boolean.toString(model.isProcessSOAPHeaders()));
        
        progArgs.add(W2J_DEFAULT_NAMESPACE);
        progArgs.add(Boolean.toString(model.isLoadDefaultNamespacePackageNameMapping()));
        
        progArgs.add(W2J_DEFAULT_EXCLUDE_NS);
        progArgs.add(Boolean.toString(model.isLoadDefaultExcludesNamepsaceMapping()));

        String xjcArgs = CommandLineUtils.getXJCArgs(model);
        if (xjcArgs.trim().length() > 0) {
            progArgs.add(W2J_XJC_ARGS + xjcArgs);
        }

        if (model.getWsdlLocation() != null) {
            progArgs.add(W2J_WSDL_LOCATION);
            progArgs.add(model.getWsdlLocation());
        }
        
        if (model.isVerbose()) {
            progArgs.add(VERBOSE);
        }
        return (String[]) progArgs.toArray(new String[progArgs.size()]);
    }

    private static String getXJCArgs(WSDL2JavaDataModel model) {
        List<String> xjcArgs = new ArrayList<String>();
        if (model.isXjcUseDefaultValues()) {
            xjcArgs.add(XJC_DV_ARG);
        }
        if (model.isXjcToString()) {
            xjcArgs.add(XJC_TS_ARG);
        }
        if (model.isXjcToStringMultiLine()) {
            xjcArgs.add(XJC_TS_MULTI_ARG);
        }
        if (model.isXjcToStringSimple()) {
            xjcArgs.add(XJC_TS_SIMPLE);
        }
        if (model.isXjcLocator()) {
            xjcArgs.add(XJC_LOCATOR_ARG);
        }
        if (model.isXjcSyncMethods()) {
            xjcArgs.add(XJC_SYNC_METHODS_ARG);
        }
        if (model.isXjcMarkGenerated()) {
            xjcArgs.add(XJC_MARK_GENERATED_ARG);
        }

        String xjcArg = xjcArgs.toString();
        xjcArg = xjcArg.replace('[', ' ');        
        xjcArg = xjcArg.replace(']', ' ');
        
        xjcArg = xjcArg.replaceAll("\\s", ""); //$NON-NLS-1$ //$NON-NLS-2$
        
        return xjcArg.trim();
    }
}
