/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.openejb.config.sys;

import org.apache.openejb.OpenEJBException;
import org.apache.openejb.config.SystemProperty;
import org.apache.openejb.jee.JAXBContextFactory;
import org.apache.openejb.loader.IO;
import org.apache.openejb.util.Join;
import org.apache.openejb.util.Messages;
import org.apache.openejb.util.Saxs;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLFilterImpl;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.transform.sax.SAXSource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public abstract class JaxbOpenejb {

    @SuppressWarnings({"unchecked"})
    public static <T> T create(final Class<T> type) {
        if (type == null) {
            throw new NullPointerException("type is null");
        }

        if (type == ConnectionManager.class) {
            return (T) createConnectionManager();
        } else if (type == Connector.class) {
            return (T) createConnector();
        } else if (type == Container.class) {
            return (T) createContainer();
        } else if (type == Deployments.class) {
            return (T) createDeployments();
        } else if (type == JndiProvider.class) {
            return (T) createJndiProvider();
        } else if (type == Openejb.class) {
            return (T) createOpenejb();
        } else if (type == ProxyFactory.class) {
            return (T) createProxyFactory();
        } else if (type == Resource.class) {
            return (T) createResource();
        } else if (type == SecurityService.class) {
            return (T) createSecurityService();
        } else if (type == ServiceProvider.class) {
            return (T) createServiceProvider();
        } else if (type == ServicesJar.class) {
            return (T) createServicesJar();
        } else if (type == TransactionManager.class) {
            return (T) createTransactionManager();
        } else if (type == Tomee.class) {
            return (T) createTomee();
        }
        throw new IllegalArgumentException("Unknown type " + type.getName());
    }

    public static <T> T create(final String type) {
        if (type == null) {
            throw new NullPointerException("type is null");
        }

        if (type.equalsIgnoreCase("ConnectionManager")) {
            return (T) createConnectionManager();
        } else if (type.equalsIgnoreCase("Connector")) {
            return (T) createConnector();
        } else if (type.equalsIgnoreCase("Container")) {
            return (T) createContainer();
        } else if (type.equalsIgnoreCase("Deployments")) {
            return (T) createDeployments();
        } else if (type.equalsIgnoreCase("JndiProvider")) {
            return (T) createJndiProvider();
        } else if (type.equalsIgnoreCase("Openejb")) {
            return (T) createOpenejb();
        } else if (type.equalsIgnoreCase("Tomee")) {
            return (T) createTomee();
        } else if (type.equalsIgnoreCase("ProxyFactory")) {
            return (T) createProxyFactory();
        } else if (type.equalsIgnoreCase("Resource")) {
            return (T) createResource();
        } else if (type.equalsIgnoreCase("SecurityService")) {
            return (T) createSecurityService();
        } else if (type.equalsIgnoreCase("ServiceProvider")) {
            return (T) createServiceProvider();
        } else if (type.equalsIgnoreCase("ServicesJar")) {
            return (T) createServicesJar();
        } else if (type.equalsIgnoreCase("TransactionManager")) {
            return (T) createTransactionManager();
        } else if (type.equalsIgnoreCase("Service")) {
            return (T) createService();
        } else if (type.equalsIgnoreCase("System-Property")) {
            return (T) createSystemProperty();
        }
        throw new IllegalArgumentException("Unknown type " + type);
    }

    public static ServicesJar readServicesJar(final String providerPath) throws OpenEJBException {

        final ClassLoader loader = Thread.currentThread().getContextClassLoader();

        final List<URL> sources = new ArrayList<URL>();

        { // Find URLs in the classpath
            final String path1 = "META-INF/" + providerPath + "/service-jar.xml";
            final String path2 = providerPath.replace('.', '/') + "/service-jar.xml";
            final List<String> paths = Arrays.asList(path1, path2);

            for (final String p : paths) {
                try {
                    final Enumeration<URL> resources = loader.getResources(p);
                    if (resources != null) {
                        sources.addAll(Collections.list(resources));
                    }
                } catch (final IOException e) {
                    throw new OpenEJBException(String.format("Unable to scan for service-jar.xml file: getResource('%s')", p), e);
                }
            }

            if (sources.size() == 0) {
                throw new OpenEJBException("No service-jar.xml files found: searched " + Join.join(" and ", paths));
            }
        }

        final ServicesJar servicesJar = new ServicesJar();

        {
            for (final URL url : sources) {
                try {
                    final InputStream read = IO.read(url);
                    try {
                        final ServicesJar jar = parseServicesJar(read);
                        servicesJar.getServiceProvider().addAll(jar.getServiceProvider());
                    } catch (final Exception e) {
                        throw new OpenEJBException("Unable to parse service-jar.xml file for provider " + providerPath + " at " + url, e);
                    } finally {
                        IO.close(read);
                    }
                } catch (final IOException e) {
                    throw new OpenEJBException("Unable to read service-jar.xml file for provider " + providerPath + " at " + url, e);
                }
            }
        }

        return servicesJar;
    }

    public static ServicesJar parseServicesJar(final InputStream in) throws ParserConfigurationException, SAXException, IOException {
        final InputSource inputSource = new InputSource(in);

        final SAXParser parser = Saxs.namespaceAwareFactory().newSAXParser();

        final ServicesJar servicesJar1 = new ServicesJar();

        parser.parse(inputSource, new OpenEJBHandler(servicesJar1));
        final ServicesJar servicesJar = servicesJar1;
        return servicesJar;
    }

    public static Openejb readConfig(final String configFile) throws OpenEJBException {
        InputStream in = null;
        try {
            if (configFile.startsWith("jar:")) {
                final URL url = new URL(configFile);
                in = IO.read(url);
            } else if (configFile.startsWith("file:")) {
                final URL url = new URL(configFile);
                in = IO.read(url);
            } else {
                in = IO.read(new File(configFile));
            }

            if (configFile.endsWith(".json")) {
                return JSonConfigReader.read(Openejb.class, in);
            }

            return readConfig(new InputSource(in));
        } catch (final MalformedURLException e) {
            throw new OpenEJBException("Unable to resolve location " + configFile, e);
        } catch (final Exception e) {
            throw new OpenEJBException("Unable to read OpenEJB configuration file at " + configFile, e);
        } finally {
            IO.close(in);
        }
    }

    public static Openejb readConfig(final InputSource in) throws IOException, SAXException, ParserConfigurationException {
        return SaxOpenejb.parse(in);
    }

    public static void writeConfig(final String configFile, final Openejb openejb) throws OpenEJBException {
        OutputStream out = null;
        try {
            final File file = new File(configFile);
            out = IO.write(file);
            marshal(Openejb.class, openejb, out);
        } catch (final IOException e) {
            throw new OpenEJBException(messages().format("conf.1040", configFile, e.getLocalizedMessage()), e);
        } catch (final MarshalException e) {
            if (e.getCause() instanceof IOException) {
                throw new OpenEJBException(messages().format("conf.1040", configFile, e.getLocalizedMessage()), e);
            } else {
                throw new OpenEJBException(messages().format("conf.1050", configFile, e.getLocalizedMessage()), e);
            }
        } catch (final ValidationException e) {
            /* TODO: Implement informative error handling here.
               The exception will say "X doesn't match the regular
               expression Y"
               This should be checked and more relevant information
               should be given -- not everyone understands regular
               expressions.
             */
            /* NOTE: This doesn't seem to ever happen. When the object graph
             * is invalid, the MarshalException is thrown, not this one as you
             * would think.
             */
            throw new OpenEJBException(messages().format("conf.1060", configFile, e.getLocalizedMessage()), e);
        } catch (final JAXBException e) {
            throw new OpenEJBException(e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (final Exception e) {
                    // no-op
                }
            }
        }
    }

    private static Messages messages() { // new is fine cause for errors only
        return new Messages("org.apache.openejb.util.resources");
    }

    public static final ThreadLocal<Set<String>> currentPublicId = new ThreadLocal<Set<String>>();

    private static final Map<Class, JAXBContext> jaxbContexts = new HashMap<Class, JAXBContext>();

    public static <T> String marshal(final Class<T> type, final Object object) throws JAXBException {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();

        marshal(type, object, baos);

        return new String(baos.toByteArray());
    }

    public static <T> void marshal(final Class<T> type, final Object object, final OutputStream out) throws JAXBException {
        final JAXBContext jaxbContext = getContext(type);
        final Marshaller marshaller = jaxbContext.createMarshaller();

        marshaller.setProperty("jaxb.formatted.output", true);

        marshaller.marshal(object, out);
    }

    public static <T> JAXBContext getContext(final Class<T> type) throws JAXBException {
        JAXBContext jaxbContext = jaxbContexts.get(type);
        if (jaxbContext == null) {
            final Thread thread = Thread.currentThread();
            final ClassLoader old = thread.getContextClassLoader();
            thread.setContextClassLoader(JaxbOpenejb.class.getClassLoader());
            try {
                jaxbContext = JAXBContextFactory.newInstance(type);
            } finally {
                thread.setContextClassLoader(old);
            }
            jaxbContexts.put(type, jaxbContext);
        }
        return jaxbContext;
    }

    public static <T> T unmarshal(final Class<T> type, final InputStream in, final boolean filter) throws ParserConfigurationException, SAXException, JAXBException {
        final InputSource inputSource = new InputSource(in);

        final SAXParser parser = Saxs.namespaceAwareFactory().newSAXParser();

        final JAXBContext ctx = getContext(type);
        final Unmarshaller unmarshaller = ctx.createUnmarshaller();
        unmarshaller.setEventHandler(new ValidationEventHandler() {
            public boolean handleEvent(final ValidationEvent validationEvent) {
                System.out.println(validationEvent);
                return false;
            }
        });

        final SAXSource source;
        if (filter) {
            final NamespaceFilter xmlFilter = new NamespaceFilter(parser.getXMLReader());
            xmlFilter.setContentHandler(unmarshaller.getUnmarshallerHandler());
            source = new SAXSource(xmlFilter, inputSource);
        } else {
            source = new SAXSource(inputSource);
        }

        currentPublicId.set(new TreeSet<String>());
        try {
            return unmarshaller.unmarshal(source, type).getValue();
        } finally {
            currentPublicId.set(null);
        }
    }

    @SuppressWarnings({"unchecked"})
    public static <T> T unmarshal(final Class<T> type, final InputStream in) throws ParserConfigurationException, SAXException, JAXBException {
        return unmarshal(type, in, true);
    }

    public static class NamespaceFilter extends XMLFilterImpl {

        public NamespaceFilter(final XMLReader xmlReader) {
            super(xmlReader);
        }

        public InputSource resolveEntity(final String publicId, final String systemId) throws SAXException, IOException {
            final Set<String> publicIds = currentPublicId.get();
            if (publicIds != null) {
                publicIds.add(publicId);
            }
            return super.resolveEntity(publicId, systemId);
        }

        public void startElement(final String uri, final String localName, final String qname, final Attributes atts) throws SAXException {
            super.startElement("http://www.openejb.org/System/Configuration", localName, qname, atts);
        }
    }


    public static ConnectionManager createConnectionManager() {
        return new ConnectionManager();
    }

    public static Connector createConnector() {
        return new Connector();
    }

    public static Container createContainer() {
        return new Container();
    }

    public static Deployments createDeployments() {
        return new Deployments();
    }

    public static Service createService() {
        return new Service();
    }

    public static SystemProperty createSystemProperty() {
        return new SystemProperty();
    }

    public static JndiProvider createJndiProvider() {
        return new JndiProvider();
    }

    public static Openejb createOpenejb() {
        return new Openejb();
    }

    private static Tomee createTomee() {
        return new Tomee();
    }

    public static ProxyFactory createProxyFactory() {
        return new ProxyFactory();
    }

    public static Resource createResource() {
        return new Resource();
    }

    public static SecurityService createSecurityService() {
        return new SecurityService();
    }

    public static ServiceProvider createServiceProvider() {
        return new ServiceProvider();
    }

    public static ServicesJar createServicesJar() {
        return new ServicesJar();
    }

    public static TransactionManager createTransactionManager() {
        return new TransactionManager();
    }

    private static class OpenEJBHandler extends DefaultHandler {
        private final PropertiesAdapter propertiesAdapter = new PropertiesAdapter();
        private final ServicesJar servicesJar;

        private ServiceProvider provider;
        private StringBuilder content;

        public OpenEJBHandler(final ServicesJar servicesJar1) {
            this.servicesJar = servicesJar1;
        }

        public void startDocument() throws SAXException {
        }

        public void startElement(final String uri, final String localName, final String qName, final Attributes att) throws SAXException {
            if (!localName.equals("ServiceProvider")) {
                return;
            }

            provider = new ServiceProvider();
            provider.setId(att.getValue("", "id"));
            provider.setService(att.getValue("", "service"));
            provider.setFactoryName(att.getValue("", "factory-name"));
            provider.setConstructor(att.getValue("", "constructor"));
            provider.setClassName(att.getValue("", "class-name"));
            provider.setParent(att.getValue("", "parent"));
            final String typesString = att.getValue("", "types");
            if (typesString != null) {
                final ListAdapter listAdapter = new ListAdapter();
                final List<String> types = listAdapter.unmarshal(typesString);
                provider.getTypes().addAll(types);
            }
            servicesJar.getServiceProvider().add(provider);
        }

        public void characters(final char[] ch, final int start, final int length) throws SAXException {
            if (content == null) {
                content = new StringBuilder();
            }
            content.append(ch, start, length);
        }

        public void endElement(final String uri, final String localName, final String qName) throws SAXException {
            if (provider == null || content == null) {
                return;
            }

            try {
                provider.getProperties().putAll(propertiesAdapter.unmarshal(content.toString()));
            } catch (final Exception e) {
                throw new SAXException(e);
            }
            provider = null;
            content = null;
        }
    }
}
