/*******************************************************************************
 * 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.Locale;
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.0.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.0.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 + "." + portTypeName + "Impl"; //$NON-NLS-1$ //$NON-NLS-2$
                model.setFullyQualifiedJavaClassName(fullyQualifiedClassName);
                SpringUtils.createJAXWSEndpoint(model);
             }
         }
    }

    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 id = ""; //$NON-NLS-1$
        String implementor =  model.getFullyQualifiedJavaClassName();
        if (implementor.indexOf(".") != -1) { //$NON-NLS-1$
            if (implementor.indexOf("Impl") != -1) { //$NON-NLS-1$
                id = implementor.substring(implementor.lastIndexOf(".") + 1,  //$NON-NLS-1$
                        implementor.lastIndexOf("Impl")).toLowerCase(Locale.getDefault()); //$NON-NLS-1$
            } else {
                id = implementor.substring(implementor.lastIndexOf(".") + 1) //$NON-NLS-1$
                    .toLowerCase(Locale.getDefault());
            }
        } else {
            if (implementor.indexOf("Impl") != -1) { //$NON-NLS-1$
                id = implementor.substring(0, implementor.lastIndexOf("Impl")).toLowerCase( //$NON-NLS-1$
                        Locale.getDefault());
            } else {
                id = implementor.toLowerCase(Locale.getDefault());
            }
        }
        return id;
    }
    
    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(); 
        }
    }
}
