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

import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Collections;
import java.util.Properties;
import java.util.Set;

import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.blueprint.NamespaceHandler;
import org.apache.aries.blueprint.NamespaceHandler2;
import org.apache.aries.blueprint.ParserContext;
import org.apache.aries.blueprint.PassThroughMetadata;
import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
import org.apache.aries.blueprint.mutable.MutablePassThroughMetadata;
import org.apache.aries.blueprint.mutable.MutableRefMetadata;
import org.apache.aries.blueprint.parser.Parser;
import org.apache.aries.blueprint.parser.ParserContextImpl;
import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
import org.osgi.framework.Bundle;
import org.osgi.service.blueprint.reflect.BeanMetadata;
import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.Metadata;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.EmptyReaderEventListener;
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
import org.springframework.beans.factory.parsing.NullSourceExtractor;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.beans.factory.parsing.ReaderEventListener;
import org.springframework.beans.factory.parsing.SourceExtractor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.NamespaceHandlerResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Blueprint NamespaceHandler wrapper for a spring NamespaceHandler
 */
public class BlueprintNamespaceHandler implements NamespaceHandler, NamespaceHandler2 {

    public static final String SPRING_CONTEXT_ID = "." + org.springframework.beans.factory.xml.ParserContext.class.getName();
    public static final String SPRING_BEAN_PROCESSOR_ID = "." + SpringBeanProcessor.class.getName();
    public static final String SPRING_APPLICATION_CONTEXT_ID = "." + ApplicationContext.class.getName();
    public static final String SPRING_BEAN_FACTORY_ID = "." + BeanFactory.class.getName();

    private final Bundle bundle;
    private final Properties schemas;
    private final org.springframework.beans.factory.xml.NamespaceHandler springHandler;

    public BlueprintNamespaceHandler(Bundle bundle, Properties schemas, org.springframework.beans.factory.xml.NamespaceHandler springHandler) {
        this.bundle = bundle;
        this.schemas = schemas;
        this.springHandler = springHandler;
        springHandler.init();
    }

    public org.springframework.beans.factory.xml.NamespaceHandler getSpringHandler() {
        return springHandler;
    }

    @Override
    public boolean usePsvi() {
        return true;
    }

    @Override
    public URL getSchemaLocation(String s) {
        if (schemas.containsKey(s)) {
            return bundle.getResource(schemas.getProperty(s));
        }
        return null;
    }

    @Override
    public Set<Class> getManagedClasses() {
        return Collections.<Class>singleton(BeanDefinition.class);
    }

    @Override
    public Metadata parse(Element element, ParserContext parserContext) {
        try {
            // Get the spring context
            org.springframework.beans.factory.xml.ParserContext springContext
                    = getOrCreateParserContext(parserContext);
            // Parse spring bean
            BeanDefinition bd = springHandler.parse(element, springContext);
            for (String name : springContext.getRegistry().getBeanDefinitionNames()) {
                if (springContext.getRegistry().getBeanDefinition(name) == bd) {
                    ComponentDefinitionRegistry registry = parserContext.getComponentDefinitionRegistry();
                    if (registry.containsComponentDefinition(name)) {
                        // Hack: we can't really make the difference between a top level bean
                        // and an inlined bean when using custom (eventually nested) namespaces.
                        // To work around the problem, the BlueprintBeanFactory will always register
                        // a BeanMetadata for each bean, but here, we unregister it and return it instead
                        // so that the caller is responsible for registering the metadata.
                        ComponentMetadata metadata = registry.getComponentDefinition(name);
                        registry.removeComponentDefinition(name);
                        return metadata;
                    }
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ComponentMetadata decorate(Node node, ComponentMetadata componentMetadata, ParserContext parserContext) {
        return componentMetadata;
    }

    private org.springframework.beans.factory.xml.ParserContext getOrCreateParserContext(ParserContext parserContext) {
        ComponentDefinitionRegistry registry = parserContext.getComponentDefinitionRegistry();
        ExtendedBlueprintContainer container = getBlueprintContainer(parserContext);
        // Create spring application context
        SpringApplicationContext applicationContext = getPassThrough(parserContext,
                SPRING_APPLICATION_CONTEXT_ID, SpringApplicationContext.class);
        if (applicationContext == null) {
            applicationContext = new SpringApplicationContext(container);
            registry.registerComponentDefinition(createPassThrough(parserContext,
                    SPRING_APPLICATION_CONTEXT_ID, applicationContext, "destroy"
            ));
        }
        // Create registry
        DefaultListableBeanFactory beanFactory = getPassThrough(parserContext,
                SPRING_BEAN_FACTORY_ID, DefaultListableBeanFactory.class);
        if (beanFactory == null) {
            beanFactory = applicationContext.getBeanFactory();
            registry.registerComponentDefinition(createPassThrough(parserContext,
                    SPRING_BEAN_FACTORY_ID, beanFactory
            ));
        }
        // Create spring parser context
        org.springframework.beans.factory.xml.ParserContext springParserContext
                = getPassThrough(parserContext, SPRING_CONTEXT_ID, org.springframework.beans.factory.xml.ParserContext.class);
        if (springParserContext == null) {
            // Create spring context
            springParserContext = createSpringParserContext(parserContext, beanFactory);
            registry.registerComponentDefinition(createPassThrough(parserContext,
                    SPRING_CONTEXT_ID, springParserContext
            ));
        }
        // Create processor
        if (!parserContext.getComponentDefinitionRegistry().containsComponentDefinition(SPRING_BEAN_PROCESSOR_ID)) {
            MutableBeanMetadata bm = parserContext.createMetadata(MutableBeanMetadata.class);
            bm.setId(SPRING_BEAN_PROCESSOR_ID);
            bm.setProcessor(true);
            bm.setScope(BeanMetadata.SCOPE_SINGLETON);
            bm.setRuntimeClass(SpringBeanProcessor.class);
            bm.setActivation(BeanMetadata.ACTIVATION_EAGER);
            bm.addArgument(createRef(parserContext, "blueprintBundleContext"), null, 0);
            bm.addArgument(createRef(parserContext, "blueprintContainer"), null, 0);
            bm.addArgument(createRef(parserContext, SPRING_APPLICATION_CONTEXT_ID), null, 0);
            registry.registerComponentDefinition(bm);
        }
        // Add the namespace handlers' bundle to the application context classloader
        for (URI uri : parserContext.getNamespaces()) {
            NamespaceHandler ns = parserContext.getNamespaceHandler(uri);
            if (ns instanceof BlueprintNamespaceHandler) {
                applicationContext.addSourceBundle(((BlueprintNamespaceHandler) ns).bundle);
            }
        }
        return springParserContext;
    }

    private ComponentMetadata createPassThrough(ParserContext parserContext, String id, Object o) {
        MutablePassThroughMetadata pt = parserContext.createMetadata(MutablePassThroughMetadata.class);
        pt.setId(id);
        pt.setObject(o);
        return pt;
    }

    private ComponentMetadata createPassThrough(ParserContext parserContext, String id, Object o, String destroy) {
        MutablePassThroughMetadata pt = parserContext.createMetadata(MutablePassThroughMetadata.class);
        pt.setId(id + ".factory");
        pt.setObject(new Holder(o));
        MutableBeanMetadata b = parserContext.createMetadata(MutableBeanMetadata.class);
        b.setId(id);
        b.setFactoryComponent(pt);
        b.setFactoryMethod("getObject");
        b.setDestroyMethod(destroy);
        return b;
    }

    public static class Holder {
        private final Object object;

        public Holder(Object object) {
            this.object = object;
        }

        public Object getObject() {
            return object;
        }
    }

    private Metadata createRef(ParserContext parserContext, String id) {
        MutableRefMetadata ref = parserContext.createMetadata(MutableRefMetadata.class);
        ref.setComponentId(id);
        return ref;
    }

    private ExtendedBlueprintContainer getBlueprintContainer(ParserContext parserContext) {
        ExtendedBlueprintContainer container = getPassThrough(parserContext, "blueprintContainer", ExtendedBlueprintContainer.class);
        if (container == null) {
            throw new IllegalStateException();
        }
        return container;
    }

    @SuppressWarnings("unchecked")
    private <T> T getPassThrough(ParserContext parserContext, String name, Class<T> clazz) {
        Metadata metadata = parserContext.getComponentDefinitionRegistry().getComponentDefinition(name);
        if (metadata instanceof BeanMetadata) {
            BeanMetadata bm = (BeanMetadata) metadata;
            if (bm.getFactoryComponent() instanceof PassThroughMetadata
                    && "getObject".equals(bm.getFactoryMethod())) {
                metadata = bm.getFactoryComponent();
            }
        }
        if (metadata instanceof PassThroughMetadata) {
            Object o = ((PassThroughMetadata) metadata).getObject();
            if (o instanceof Holder) {
                o = ((Holder) o).getObject();
            }
            return (T) o;
        } else {
            return null;
        }
    }

    private org.springframework.beans.factory.xml.ParserContext createSpringParserContext(final ParserContext parserContext, DefaultListableBeanFactory registry) {
        try {
            SpringVersionBridgeXmlBeanDefinitionReader xbdr = new SpringVersionBridgeXmlBeanDefinitionReader(registry);
            Resource resource = new UrlResource(parserContext.getSourceNode().getOwnerDocument().getDocumentURI());
            ProblemReporter problemReporter = new FailFastProblemReporter();
            ReaderEventListener listener = new EmptyReaderEventListener();
            SourceExtractor extractor = new NullSourceExtractor();
            NamespaceHandlerResolver resolver = new SpringNamespaceHandlerResolver(parserContext);
            xbdr.setProblemReporter(problemReporter);
            xbdr.setEventListener(listener);
            xbdr.setSourceExtractor(extractor);
            xbdr.setNamespaceHandlerResolver(resolver);
            xbdr.setEntityResolver(new EntityResolver() {
                @Override
                public InputSource resolveEntity(String publicId, String systemId) throws IOException {
                    for (URI ns : parserContext.getNamespaces()) {
                        NamespaceHandler nh = parserContext.getNamespaceHandler(ns);
                        URL url = null;
                        if (publicId != null) {
                            url = nh.getSchemaLocation(publicId);
                        }
                        if (url == null && systemId != null) {
                            url = nh.getSchemaLocation(systemId);
                        }
                        if (url != null) {
                            InputSource is = new InputSource();
                            is.setPublicId(publicId);
                            is.setSystemId(systemId);
                            is.setByteStream(url.openStream());
                            return is;
                        }
                    }
                    return null;
                }
            });
            XmlReaderContext xmlReaderContext = xbdr.createReaderContext(resource);
            BeanDefinitionParserDelegate bdpd = new BeanDefinitionParserDelegate(xmlReaderContext);
            return new org.springframework.beans.factory.xml.ParserContext(xmlReaderContext, bdpd);
        } catch (Exception e) {
            throw new RuntimeException("Error creating spring parser context", e);
        }
    }

    /**
     * Some methods are protected in Spring 3.x, hence overridden methods in this class to make them available.
     */
    private class SpringVersionBridgeXmlBeanDefinitionReader extends XmlBeanDefinitionReader {

        public SpringVersionBridgeXmlBeanDefinitionReader(final BeanDefinitionRegistry registry) {
            super(registry);
        }

        @Override
        public XmlReaderContext createReaderContext(final Resource resource) {
            return super.createReaderContext(resource);
        }
    }


}
