/*******************************************************************************
 * 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;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;

@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_AUTO_NAME_RESOLUTION = "-autoNameResolution"; //$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.getDefaultRuntimeVersion().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 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).toOSString());

        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).toOSString());

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

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

        if (model.isVerbose()) {
            progArgs.add(VERBOSE);
        }

        return 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.isUseDefaultValues()) {
                progArgs.add(W2J_DEFAULT_VALUES);
            }

            if (model.getDefaultRuntimeVersion().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.isNoAddressBinding()) {
                    progArgs.add(W2J_NO_ADDRESS_BINDING);
                }
            }

            progArgs.add(model.getWsdlURL().toExternalForm());
        }
        return 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)) {
            progArgs.add(GEN_CLIENT);

            // Add WSLD2Java args
            progArgs.addAll(Arrays.asList(CommandLineUtils.getWSDL2JavaProgramArguments(model)));
        }
        return 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).toOSString());

        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()));

        if (model.isAutoNameResolution() && CXFModelUtils.isAutoNameResolutionPermitted()) {
            progArgs.add(W2J_AUTO_NAME_RESOLUTION);
        }

        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 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();
    }
}
