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