/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Mike Norman - Oct 30 2008: some re-work of DBWSPackager hierarchy
package org.eclipse.persistence.tools.dbws;

import static org.eclipse.persistence.internal.xr.Util.DBWS_WSDL;
import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.noArchive;
import static org.eclipse.persistence.tools.dbws.Util.DBWS_PROVIDER_CLASS_FILE;
import static org.eclipse.persistence.tools.dbws.Util.DBWS_PROVIDER_SOURCE_FILE;
import static org.eclipse.persistence.tools.dbws.Util.DOT_CLASS;
import static org.eclipse.persistence.tools.dbws.Util.PROVIDER_LISTENER_CLASS_FILE;
import static org.eclipse.persistence.tools.dbws.Util.PROVIDER_LISTENER_SOURCE_FILE;

//javase imports
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

//java eXtension imports
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;

import org.eclipse.persistence.internal.dbws.ProviderHelper;

//EclipseLink imports
import _dbws.ProviderListener;

/**
 * <p>
 * <b>INTERNAL:</b> ProviderPackager extends {@link XRPackager}. It is responsible for generating<br>
 * the {@code jakarta.servlet.ServletContextListener} and the JAX-WS {@code jakarta.xml.ws.Provider} and saves the generated WSDL
 * to ${stageDir}
 * <pre>
 * ${PACKAGER_ROOT}
 *   | DBWSProvider.class     -- code-generated jakarta.xml.ws.Provider
 *   | ProviderListener.class -- code-generated jakarta.servlet.ServletContextListener
 * </pre>
 *
 * @author Mike Norman - michael.norman@oracle.com
 * @since EclipseLink 1.x
 */
public class ProviderPackager extends XRPackager {

    public static final String PROVIDER_NAME = "_dbws.DBWSProvider";

    public static final String PROVIDER_LISTENER_SOURCE =
        "package _dbws;\n\n" +
        "import jakarta.servlet.ServletContext;\n" +
        "import jakarta.servlet.ServletContextEvent;\n" +
        "import jakarta.servlet.ServletContextListener;\n\n" +
        "public class ProviderListener implements ServletContextListener {\n\n" +
        "    public static ServletContext SC = null;\n\n" +
        "    public  ProviderListener() {\n" +
        "        super();\n" +
        "    }\n\n" +
        "    public void contextInitialized(ServletContextEvent sce) {\n" +
        "        SC = sce.getServletContext();\n" +
        "    }\n\n" +
        "    public void contextDestroyed(ServletContextEvent sce) {\n" +
        "        // no-op\n" +
        "    }\n" +
        "}\n";

    public static final String DBWS_PROVIDER_SOURCE_PREAMBLE_START =
        "package _dbws;\n" +
        "\n//Java extension libraries\n" +
        "import jakarta.annotation.PostConstruct;\n" +
        "import jakarta.annotation.PreDestroy;\n" +
        "import jakarta.annotation.Resource;\n" +
        "import jakarta.servlet.ServletContext;\n" +
        "import jakarta.xml.soap.SOAPMessage;\n" +
        "import jakarta.xml.ws.BindingType;\n" +
        "import jakarta.xml.ws.Provider;\n" +
        "import jakarta.xml.ws.ServiceMode;\n" +
        "import jakarta.xml.ws.WebServiceContext;\n" +
        "import jakarta.xml.ws.WebServiceProvider;\n" +
        "import static jakarta.xml.ws.Service.Mode.MESSAGE;\n";
    public static final String DBWS_PROVIDER_SOURCE_SOAP11HTTP_MTOM_BINDING =
        "import static jakarta.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING;\n";
    public static final String DBWS_PROVIDER_SOURCE_SOAP12HTTP_BINDING =
        "import static jakarta.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING;\n";
    public static final String DBWS_PROVIDER_SOURCE_SOAP12HTTP_MTOM_BINDING =
        "import static jakarta.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING;\n";
    public static final String DBWS_PROVIDER_SOURCE_PREAMBLE_END =
        "\n//EclipseLink imports\n" +
        "import " + ProviderHelper.class.getName() + ";\n" +
        "\n@WebServiceProvider(\n";
    public static final String DBWS_PROVIDER_SOURCE_WSDL_LOCATION =
        "    wsdlLocation = \"WEB-INF/wsdl/eclipselink-dbws.wsdl\",\n";
    public static final String DBWS_PROVIDER_SOURCE_SERVICE_NAME =
        "    serviceName = \"";
    public static final String DBWS_PROVIDER_SOURCE_PORT_NAME =
        "\",\n    portName = \"";
    public static final String DBWS_PROVIDER_SOURCE_TARGET_NAMESPACE =
        "\",\n    targetNamespace = \"";
    public static final String DBWS_PROVIDER_SOURCE_SUFFIX =
        "\"\n)\n@ServiceMode(MESSAGE)\n";

    public static final String DBWS_PROVIDER_SOAP12_BINDING =
        "@BindingType(value=SOAP12HTTP_BINDING)\n";
    public static final String DBWS_PROVIDER_SOAP11_MTOM_BINDING =
        "@BindingType(value=SOAP11HTTP_MTOM_BINDING)\n";
    public static final String DBWS_PROVIDER_SOAP12_MTOM_BINDING =
        "@BindingType(value=SOAP12HTTP_MTOM_BINDING)\n";

    public static final String DBWS_PROVIDER_SOURCE_CLASSDEF =
        "public class DBWSProvider extends ProviderHelper implements Provider<SOAPMessage> {\n\n" +
        "    // Container injects wsContext here\n" +
        "    @Resource\n" +
        "    protected WebServiceContext wsContext;\n\n" +
        "    public  DBWSProvider() {\n" +
        "        super();\n" +
        "    }\n\n" +
        "    @PostConstruct\n" +
        "    public void init() {\n" +
        "        ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();\n" +
        "        ServletContext sc = ProviderListener.SC;\n" +
        "        boolean mtomEnabled = false;\n" +
        "        BindingType thisBindingType = this.getClass().getAnnotation(BindingType.class);\n" +
        "        if (thisBindingType != null) {\n" +
        "            if (thisBindingType.value().toLowerCase().contains(\"mtom=true\")) {\n" +
        "                mtomEnabled = true;\n" +
        "            }\n" +
        "        }\n" +
        "        super.init(parentClassLoader, sc, mtomEnabled);\n" +
        "    }\n\n" +
        "    @Override\n" +
        "    public SOAPMessage invoke(SOAPMessage request) {\n" +
        "        if (wsContext != null) {\n" +
        "            setMessageContext(wsContext.getMessageContext());\n" +
        "        }\n" +
        "        return super.invoke(request);\n" +
        "    }\n\n" +
        "    @Override\n" +
        "    @PreDestroy\n" +
        "    public void destroy() {\n" +
        "        super.destroy();\n" +
        "    }\n" +
        "};\n";

    public ProviderPackager() {
        this(new WarArchiver(),"provider", noArchive);
    }
    protected ProviderPackager(Archiver archiver, String packagerLabel, ArchiveUse useJavaArchive) {
        super(archiver, packagerLabel, useJavaArchive);
    }

    @Override
    public Archiver buildDefaultArchiver() {
        return new WarArchiver(this);
    }

    @Override
    public OutputStream getWSDLStream() throws FileNotFoundException {
        return new FileOutputStream(new File(stageDir, DBWS_WSDL));
    }

    @Override
    public OutputStream getProviderClassStream() throws FileNotFoundException {
        return new FileOutputStream(new File(stageDir, DBWS_PROVIDER_CLASS_FILE));
    }

    @Override
    public OutputStream getProviderSourceStream() throws FileNotFoundException {
        return new FileOutputStream(new File(stageDir, DBWS_PROVIDER_SOURCE_FILE));
    }

    @Override
    public OutputStream getProviderListenerSourceStream() throws FileNotFoundException {
        return new FileOutputStream(new File(stageDir, PROVIDER_LISTENER_SOURCE_FILE));
    }

    @Override
    public OutputStream getProviderListenerClassStream() throws FileNotFoundException {
        return new FileOutputStream(new File(stageDir, PROVIDER_LISTENER_CLASS_FILE));

    }

    static final int DEFAULT_BUFFER_SIZE = 4096;
    @Override
    public void writeProvider(OutputStream sourceProviderStream, OutputStream classProviderStream,
        OutputStream sourceProviderListenerStream, OutputStream classProviderListenerStream,
        DBWSBuilder builder) {

        StringBuilder source = new StringBuilder(DBWS_PROVIDER_SOURCE_PREAMBLE_START);
        if (builder.usesSOAP12()) {
            if (builder.mtomEnabled()) {
                source.append(DBWS_PROVIDER_SOURCE_SOAP12HTTP_MTOM_BINDING);
            } else {
                source.append(DBWS_PROVIDER_SOURCE_SOAP12HTTP_BINDING);
            }
        } else {
            if (builder.mtomEnabled()) {
                source.append(DBWS_PROVIDER_SOURCE_SOAP11HTTP_MTOM_BINDING);
            }
        }
        source.append(new StringBuilder(DBWS_PROVIDER_SOURCE_PREAMBLE_END));
        String wsdlPathPrevix = getWSDLPathPrefix();
        if (wsdlPathPrevix != null) {
            source.append(DBWS_PROVIDER_SOURCE_WSDL_LOCATION);
        }
        source.append(DBWS_PROVIDER_SOURCE_SERVICE_NAME);
        String serviceName = builder.getWSDLGenerator().getServiceName();
        source.append(serviceName);
        source.append(DBWS_PROVIDER_SOURCE_PORT_NAME);
        source.append(serviceName + "Port");
        source.append(DBWS_PROVIDER_SOURCE_TARGET_NAMESPACE);
        source.append(builder.getWSDLGenerator().getServiceNameSpace());
        source.append(DBWS_PROVIDER_SOURCE_SUFFIX);
        if (builder.usesSOAP12()) {
            if (builder.mtomEnabled()) {
                source.append(DBWS_PROVIDER_SOAP12_MTOM_BINDING);
            }
            else {
                source.append(DBWS_PROVIDER_SOAP12_BINDING);
            }
        }
        else {
            if (builder.mtomEnabled()) {
                source.append(DBWS_PROVIDER_SOAP11_MTOM_BINDING);
            }
            // else the default BindingType, don't have to explicitly set it
        }
        source.append(DBWS_PROVIDER_SOURCE_CLASSDEF);
        if (sourceProviderStream != __nullStream) {
            OutputStreamWriter osw =
                new OutputStreamWriter(new BufferedOutputStream(sourceProviderStream));
            try {
                osw.write(source.toString());
                osw.flush();
            }
            catch (IOException e) {}
        }

        if (classProviderStream != __nullStream) {
            InMemoryCompiler providerCompiler = new InMemoryCompiler(PROVIDER_NAME);
            if (providerCompiler.getCompiler() == null) {
                throw new IllegalStateException("DBWSBuilder cannot compile DBWSProvider code\n" +
                    "Please ensure that tools.jar is on your classpath");
            }
            byte[] bytes = providerCompiler.compile(source);
            if (bytes.length == 0) {
                DiagnosticCollector<JavaFileObject> collector = providerCompiler.getDiagnosticsCollector();
                StringBuilder diagBuf =
                    new StringBuilder("DBWSBuilder cannot generate ProviderListener code " +
                        "(likely servlet jar missing from classpath)\n");
                for (Diagnostic<? extends JavaFileObject> d : collector.getDiagnostics()) {
                    if (d.getKind() == Diagnostic.Kind.ERROR) {
                        diagBuf.append(d.getMessage(null));
                        diagBuf.append("\n");
                    }
                }
                throw new IllegalStateException(diagBuf.toString());
            }
            else {
                try {
                    classProviderStream.write(bytes, 0, bytes.length);
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        if (sourceProviderListenerStream != __nullStream) {
            OutputStreamWriter osw =
                new OutputStreamWriter(new BufferedOutputStream(sourceProviderListenerStream));
            try {
                osw.write(PROVIDER_LISTENER_SOURCE);
                osw.flush();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (classProviderListenerStream != __nullStream) {
            try {
                InputStream is = this.getClass().getClassLoader().getResourceAsStream(
                    ProviderListener.class.getName().replace('.', '/') + DOT_CLASS);
                byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
                int n = 0;
                while (-1 != (n = is.read(buffer))) {
                    classProviderListenerStream.write(buffer, 0, n);
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
