/*******************************************************************************
 * 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.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.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;

/**
 * @author sclarke
 */
@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", //$NON-NLS-1$
            "http://www.w3.org/2001/XMLSchema-instance"); //$NON-NLS-1$
    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);
        }

        boolean exists = false;
        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)) {
                            exists = true;
                            break;
                        }
                    }                    
                }
            } catch (JDOMException jdome) {
                CXFCorePlugin.log(jdome);
            } finally {
               springConfigInputSteam.close();
            }
        }
        return exists;
    }
    
    @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);
             }
         }
    }

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