/*******************************************************************************
 * 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.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.xml.namespace.QName;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFDataModel;
import org.eclipse.jst.ws.internal.cxf.core.model.WSDL2JavaDataModel;
import org.eclipse.jst.ws.jaxws.core.utils.WSDLUtils;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

@SuppressWarnings("restriction")
public final class SpringUtils {
    private static Namespace SPRING_BEANS_NS = Namespace
    .getNamespace("http://www.springframework.org/schema/beans"); //$NON-NLS-1$
    private static Namespace XMLNS_XSI = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); //$NON-NLS-1$ //$NON-NLS-2$
    private static Namespace JAXWS_NS = Namespace.getNamespace("jaxws", "http://cxf.apache.org/jaxws"); //$NON-NLS-1$ //$NON-NLS-2$
    private static Namespace SOAP_NS = Namespace.getNamespace("soap", "http://cxf.apache.org/bindings/soap"); //$NON-NLS-1$ //$NON-NLS-2$

    private static String DOC_ROOT = "beans"; //$NON-NLS-1$

    private SpringUtils() {
    }

    public static IFile getBeansFile(IProject project) throws IOException {
        IFile beansFile = null;
        IPath webContentPath = J2EEUtils.getWebContentPath(project);
        if (!webContentPath.hasTrailingSeparator()) {
            webContentPath = webContentPath.addTrailingSeparator();

            IPath webINFPath = webContentPath.append(new Path("WEB-INF/")); //$NON-NLS-1$
            IFolder webINFFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webINFPath);
            beansFile = webINFFolder.getFile("cxf-beans.xml"); //$NON-NLS-1$
            if (!beansFile.exists()) {
                try {
                    IProgressMonitor progressMonitor = new NullProgressMonitor();
                    beansFile.create(new ByteArrayInputStream(new byte[] {}), true, progressMonitor);
                    createBaseBeansFile(beansFile);
                } catch (CoreException ce) {
                    CXFCorePlugin.log(ce);
                }
            }
        }
        return beansFile;
    }

    public static IFile getBeansFile(String projectName) throws IOException {
        return SpringUtils.getBeansFile(FileUtils.getProject(projectName));
    }

    /**
     * Returns a handle to the cxf-servlet file in the Web projects WEB-INF
     * folder.
     * 
     * @param project
     * @return {@link IFile}
     */
    public static IFile getCXFServlet(IProject project) throws IOException {
        IFile cxfServlet = null;
        IPath webContentPath = J2EEUtils.getWebContentPath(project);
        if (!webContentPath.hasTrailingSeparator()) {
            webContentPath = webContentPath.addTrailingSeparator();

            IPath webINFPath = webContentPath.append(new Path("WEB-INF/")); //$NON-NLS-1$
            IFolder webINFFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webINFPath);
            cxfServlet = webINFFolder.getFile("cxf-servlet.xml"); //$NON-NLS-1$
            if (!cxfServlet.exists()) {
                try {
                    IProgressMonitor progressMonitor = new NullProgressMonitor();

                    cxfServlet.create(new ByteArrayInputStream(new byte[] {}), true, progressMonitor);
                    createBaseCXFServletFile(cxfServlet);
                } catch (CoreException ce) {
                    CXFCorePlugin.log(ce.getStatus());
                }
            }
        }
        return cxfServlet;
    }

    public static IFile getCXFServlet(String projectName) throws IOException {
        return SpringUtils.getCXFServlet(FileUtils.getProject(projectName));
    }

    private static void createBaseCXFServletFile(IFile cxfServlet)  throws IOException {
        Element beans = new Element(DOC_ROOT);
        beans.setNamespace(SPRING_BEANS_NS);
        beans.addNamespaceDeclaration(XMLNS_XSI);
        beans.addNamespaceDeclaration(JAXWS_NS);
        beans.addNamespaceDeclaration(SOAP_NS);

        Attribute schemaLocation = new Attribute(
                "schemaLocation", //$NON-NLS-1$
                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd " //$NON-NLS-1$
                + "http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd " //$NON-NLS-1$
                + "http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd", XMLNS_XSI); //$NON-NLS-1$

        beans.setAttribute(schemaLocation);

        writeConfig(new Document(beans), cxfServlet);
    }

    private static void createBaseBeansFile(IFile beansFile) throws IOException {
        Element beans = new Element(DOC_ROOT);
        beans.setNamespace(SPRING_BEANS_NS);
        beans.addNamespaceDeclaration(XMLNS_XSI);
        beans.addNamespaceDeclaration(JAXWS_NS);

        Attribute schemaLocation = new Attribute(
                "schemaLocation", //$NON-NLS-1$
                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd " //$NON-NLS-1$
                + "http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd", XMLNS_XSI); //$NON-NLS-1$

        beans.setAttribute(schemaLocation);

        Element importCXFResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
        importCXFResource.setAttribute("resource", "classpath:META-INF/cxf/cxf.xml"); //$NON-NLS-1$ //$NON-NLS-2$

        Element importCXFSoapExtensionResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
        importCXFSoapExtensionResource.setAttribute("resource", //$NON-NLS-1$
        "classpath:META-INF/cxf/cxf-extension-soap.xml"); //$NON-NLS-1$

        Element importCXFServeltResource = new Element("import", SPRING_BEANS_NS); //$NON-NLS-1$
        importCXFServeltResource.setAttribute("resource", "classpath:META-INF/cxf/cxf-servlet.xml"); //$NON-NLS-1$ //$NON-NLS-2$

        beans.addContent(importCXFResource);
        beans.addContent(importCXFSoapExtensionResource);
        beans.addContent(importCXFServeltResource);

        writeConfig(new Document(beans), beansFile);
    }

    public static boolean isSpringBeansFile(IFile springBeansFile) throws IOException {
        FileInputStream springBeansInputStream = new FileInputStream(springBeansFile.getLocation().toFile());
        if (springBeansInputStream.available() > 0) {
            SAXBuilder builder = new SAXBuilder();
            try {
                Document doc = builder.build(springBeansInputStream);
                Element root = doc.getRootElement();
                if (root.getName().equals(DOC_ROOT) && root.getNamespace().equals(SPRING_BEANS_NS)) {
                    return true;
                }
            } catch (JDOMException jdome) {
                CXFCorePlugin.log(jdome);
            } finally {
                springBeansInputStream.close();
            }
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    private static boolean isBeanDefined(CXFDataModel cxfDataModel, String projectName, String elementName,
            Namespace namespace, String id) throws IOException {
        IFile springConfigFile = null;

        if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
            springConfigFile = SpringUtils.getBeansFile(projectName);
        } else {
            springConfigFile = SpringUtils.getCXFServlet(projectName);
        }

        if (isSpringBeansFile(springConfigFile)) {
            SAXBuilder builder = new SAXBuilder();
            FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
                    .toFile());
            try {
                Document doc = builder.build(springConfigInputSteam);
                Element beans = doc.getRootElement();

                List<Element> endpoints = beans.getChildren(elementName, namespace);
                for (Element element : endpoints) {
                    if (element != null && element.getAttribute("id") != null) { //$NON-NLS-1$
                        Attribute idAttribute = element.getAttribute("id"); //$NON-NLS-1$
                        if (idAttribute.getValue().equals(id)) {
                            return true;
                        }
                    }
                }
            } catch (JDOMException jdome) {
                CXFCorePlugin.log(jdome);
            } finally {
                springConfigInputSteam.close();
            }
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    public static String getEndpointAddress(IProject project, String jaxwsEndpointId) throws IOException {
        IFile springConfigFile = null;
        if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
            springConfigFile = SpringUtils.getBeansFile(project);
        } else {
            springConfigFile = SpringUtils.getCXFServlet(project);
        }
        if (isSpringBeansFile(springConfigFile)) {
            SAXBuilder builder = new SAXBuilder();
            FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
                    .toFile());
            try {
                Document doc = builder.build(springConfigInputSteam);
                Element beans = doc.getRootElement();
                List<Element> endpoints = beans.getChildren("endpoint", JAXWS_NS); //$NON-NLS-1$
                for (Element element : endpoints) {
                    if (element != null && element.getAttribute("id") != null) { //$NON-NLS-1$
                        Attribute idAttribute = element.getAttribute("id"); //$NON-NLS-1$
                        if (idAttribute.getValue().equals(jaxwsEndpointId)) {
                            return element.getAttribute("address").getValue(); //$NON-NLS-1$
                        }
                    }
                }
            } catch (JDOMException jdome) {
                CXFCorePlugin.log(jdome);
            } finally {
                springConfigInputSteam.close();
            }
        }
        return ""; //$NON-NLS-1$
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void createConfigurationFromWSDL(WSDL2JavaDataModel model) throws IOException {
        String targetNamespace = model.getTargetNamespace();
        String packageName = model.getIncludedNamespaces().get(targetNamespace);

        Definition definition = model.getWsdlDefinition();
        Map servicesMap = definition.getServices();
        Set<Map.Entry> servicesSet = servicesMap.entrySet();
        for (Map.Entry serviceEntry : servicesSet) {
            Service service = (Service) serviceEntry.getValue();
            model.setServiceName(service.getQName().getLocalPart());
            Map portsMap = service.getPorts();
            Set<Map.Entry> portsSet = portsMap.entrySet();
            for (Map.Entry portEntry : portsSet) {
                Port port = (Port) portEntry.getValue();
                model.setEndpointName(port.getName());
                PortType portType = port.getBinding().getPortType();
                QName qName = portType.getQName();
                String portTypeName = qName.getLocalPart();
                String fullyQualifiedClassName = packageName + "." + //$NON-NLS-1$
                convertPortTypeName(portTypeName) + "Impl"; //$NON-NLS-1$
                model.setFullyQualifiedJavaClassName(fullyQualifiedClassName);
                SpringUtils.createJAXWSEndpoint(model);
            }
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void loadSpringConfigInformationFromWSDL(CXFDataModel model) {
        IFile wsdlFile = WSDLUtils.getWSDLFolder(model.getProjectName()).getFile(model.getWsdlFileName());
        if (wsdlFile.exists()) {
            try {
                model.setWsdlURL(wsdlFile.getLocationURI().toURL());
                Definition definition = WSDLUtils.readWSDL(model.getWsdlURL());
                Map servicesMap = definition.getServices();
                Set<Map.Entry> servicesSet = servicesMap.entrySet();
                for (Map.Entry serviceEntry : servicesSet) {
                    Service service = (Service) serviceEntry.getValue();
                    model.setServiceName(service.getQName().getLocalPart());
                    Map portsMap = service.getPorts();
                    Set<Map.Entry> portsSet = portsMap.entrySet();
                    for (Map.Entry portEntry : portsSet) {
                        Port port = (Port) portEntry.getValue();
                        model.setEndpointName(port.getName());
                    }
                }
                model.setWsdlDefinition(definition);
            } catch (MalformedURLException murle) {
                CXFCorePlugin.log(murle);
            } catch (IOException ioe) {
                CXFCorePlugin.log(ioe);
            }
        }
    }

    private static String convertPortTypeName(String portTypeName) {
        String[] segments = portTypeName.split("[\\-\\.\\:\\_\\u00b7\\u0387\\u06dd\\u06de]");

        StringBuilder stringBuilder = new StringBuilder();
        for (String segment : segments) {
            if (segment.length() == 0) {
                continue;
            }
            char firstCharacter = segment.charAt(0);
            if (!Character.isDigit(firstCharacter) && Character.isLowerCase(firstCharacter)) {
                segment = segment.substring(0, 1).toUpperCase() + segment.substring(1);
            }

            for (int i = 1; i < segment.length(); i++) {
                char currentChar = segment.charAt(i);
                char precedingChar = segment.charAt(i - 1);
                if (Character.isLetter(currentChar) && Character.isDigit(precedingChar)
                        && Character.isLowerCase(currentChar)) {
                    segment = segment.substring(0, i) + segment.substring(i, i + 1).toUpperCase()
                    + segment.substring(i + 1, segment.length());
                }
            }
            stringBuilder.append(segment);
        }
        return stringBuilder.toString();
    }

    public static void createJAXWSEndpoint(CXFDataModel model) throws IOException {
        String projectName = model.getProjectName();

        IFile springConfigFile = null;
        if (CXFCorePlugin.getDefault().getJava2WSContext().isUseSpringApplicationContext()) {
            springConfigFile = SpringUtils.getBeansFile(projectName);
        } else {
            springConfigFile = SpringUtils.getCXFServlet(projectName);
        }

        if (isSpringBeansFile(springConfigFile)) {
            SAXBuilder builder = new SAXBuilder();
            FileInputStream springConfigInputSteam = new FileInputStream(springConfigFile.getLocation()
                    .toFile());
            try {
                Document doc = builder.build(springConfigInputSteam);
                Element beans = doc.getRootElement();

                Element jaxwsEndpoint = new Element("endpoint", JAXWS_NS); //$NON-NLS-1$

                String id = getJAXWSEndpointID(model);
                model.setConfigId(id);
                jaxwsEndpoint.setAttribute("id", id); //$NON-NLS-1$

                jaxwsEndpoint.setAttribute("implementor", model.getFullyQualifiedJavaClassName()); //$NON-NLS-1$

                if (model.getConfigWsdlLocation() != null) {
                    jaxwsEndpoint.setAttribute("wsdlLocation", model.getConfigWsdlLocation()); //$NON-NLS-1$

                    if (model.getEndpointName() != null && model.getServiceName() != null) {
                        jaxwsEndpoint.setAttribute("endpointName", "tns:" + model.getEndpointName()); //$NON-NLS-1$ //$NON-NLS-2$
                        jaxwsEndpoint.setAttribute("serviceName", "tns:" + model.getServiceName()); //$NON-NLS-1$ //$NON-NLS-2$

                        Namespace XMLNS_TNS = Namespace.getNamespace("tns", model.getTargetNamespace()); //$NON-NLS-1$
                        jaxwsEndpoint.addNamespaceDeclaration(XMLNS_TNS);
                    }
                }

                if (model.getEndpointName() != null) {
                    jaxwsEndpoint.setAttribute("address", "/" + model.getEndpointName()); //$NON-NLS-1$ //$NON-NLS-2$
                } else {
                    jaxwsEndpoint.setAttribute("address", "/" + id); //$NON-NLS-1$ //$NON-NLS-2$
                }


                Element jaxwsFeatures = new Element("features", JAXWS_NS); //$NON-NLS-1$
                Element bean = new Element("bean", SPRING_BEANS_NS); //$NON-NLS-1$
                bean.setAttribute("class", "org.apache.cxf.feature.LoggingFeature"); //$NON-NLS-1$ //$NON-NLS-2$
                jaxwsFeatures.addContent(bean);
                jaxwsEndpoint.addContent(jaxwsFeatures);

                if (!isBeanDefined(model, projectName, "endpoint", JAXWS_NS, id)) { //$NON-NLS-1$
                    beans.addContent(jaxwsEndpoint);

                    writeConfig(doc, springConfigFile);
                }
            } catch (JDOMException jdome) {
                CXFCorePlugin.log(jdome);
            } finally {
                springConfigInputSteam.close();
            }
        }
    }

    private static String getJAXWSEndpointID(CXFDataModel model) {
        String implementor = model.getFullyQualifiedJavaClassName();
        if (implementor.indexOf(".") != -1) { //$NON-NLS-1$
            implementor = implementor.substring(implementor.lastIndexOf(".") + 1, implementor.length());
        }
        if (!implementor.startsWith("Impl") && implementor.indexOf("Impl") != -1) {
            implementor = implementor.substring(0, implementor.indexOf("Impl")).toLowerCase(); //$NON-NLS-1$;
        } else {
            implementor = implementor.toLowerCase();
        }
        return implementor;
    }

    private static void writeConfig(Document document, IFile springConfigFile) throws IOException {
        OutputStream outputStream = new FileOutputStream(springConfigFile.getLocation().toFile());
        try {
            XMLOutputter outputter = new XMLOutputter();
            outputter.output(document, outputStream);
            springConfigFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
            FileUtils.formatXMLFile(springConfigFile);
        } catch (CoreException ce) {
            CXFCorePlugin.log(ce.getStatus());
        } finally {
            outputStream.close();
        }
    }
}
