/*
 * 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.sling.scripting.thymeleaf.internal;

import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.servlet.ServletContext;

import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
import org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.ITemplateEngine;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.cache.ICacheManager;
import org.thymeleaf.context.IEngineContextFactory;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.linkbuilder.ILinkBuilder;
import org.thymeleaf.linkbuilder.StandardLinkBuilder;
import org.thymeleaf.messageresolver.IMessageResolver;
import org.thymeleaf.messageresolver.StandardMessageResolver;
import org.thymeleaf.standard.StandardDialect;
import org.thymeleaf.templateparser.markup.decoupled.IDecoupledTemplateLogicResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;

@Component(
    service = ScriptEngineFactory.class,
    immediate = true,
    property = {
        Constants.SERVICE_DESCRIPTION + "=ScriptEngineFactory for Sling Scripting Thymeleaf",
        Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
    }
)
@Designate(
    ocd = ThymeleafScriptEngineFactoryConfiguration.class
)
public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFactory {

    @Reference(
        cardinality = ReferenceCardinality.AT_LEAST_ONE,
        policy = ReferencePolicy.DYNAMIC,
        bind = "addTemplateResolver",
        unbind = "removeTemplateResolver"
    )
    private volatile List<ITemplateResolver> templateResolvers;

    @Reference(
        cardinality = ReferenceCardinality.AT_LEAST_ONE,
        policy = ReferencePolicy.DYNAMIC,
        bind = "addMessageResolver",
        unbind = "removeMessageResolver"
    )
    private volatile List<IMessageResolver> messageResolvers;

    @Reference(
        cardinality = ReferenceCardinality.AT_LEAST_ONE,
        policy = ReferencePolicy.DYNAMIC,
        bind = "addDialect",
        unbind = "removeDialect"
    )
    private volatile List<IDialect> dialects;

    @Reference(
        cardinality = ReferenceCardinality.MULTIPLE,
        policy = ReferencePolicy.DYNAMIC,
        bind = "addLinkBuilder",
        unbind = "removeLinkBuilder"
    )
    private volatile List<ILinkBuilder> linkBuilders;

    @Reference(
        cardinality = ReferenceCardinality.OPTIONAL,
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY,
        bind = "setDecoupledTemplateLogicResolver",
        unbind = "unsetDecoupledTemplateLogicResolver"
    )
    private volatile IDecoupledTemplateLogicResolver decoupledTemplateLogicResolver;

    @Reference(
        cardinality = ReferenceCardinality.OPTIONAL,
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY,
        bind = "setCacheManager",
        unbind = "unsetCacheManager"
    )
    private volatile ICacheManager cacheManager;

    @Reference(
        cardinality = ReferenceCardinality.OPTIONAL,
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY,
        bind = "setEngineContextFactory",
        unbind = "unsetEngineContextFactory"
    )
    private volatile IEngineContextFactory engineContextFactory;

    @Reference(
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY
    )
    private volatile ScriptingResourceResolverProvider scriptingResourceResolverProvider;

    @Reference(
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY,
        target = "(name=org.apache.sling)"
    )
    private volatile ServletContext servletContext;

    private ThymeleafScriptEngineFactoryConfiguration configuration;

    private BundleContext bundleContext;

    private TemplateEngine templateEngine;

    private ServiceRegistration<ITemplateEngine> serviceRegistration;

    private final Object lock = new Object();

    private static final String THYMELEAF_PROPERTIES = "/org/thymeleaf/thymeleaf.properties";

    private final Logger logger = LoggerFactory.getLogger(ThymeleafScriptEngineFactory.class);

    public ThymeleafScriptEngineFactory() {
    }

    protected void addTemplateResolver(final ITemplateResolver templateResolver) {
        synchronized (lock) {
            logger.debug("adding template resolver '{}'", templateResolver.getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.addTemplateResolver(templateResolver);
            }
        }
    }

    protected void removeTemplateResolver(final ITemplateResolver templateResolver) {
        synchronized (lock) {
            logger.debug("removing template resolver '{}'", templateResolver.getName());
            serviceTemplateEngine();
        }
    }

    protected void addMessageResolver(final IMessageResolver messageResolver) {
        synchronized (lock) {
            logger.debug("adding message resolver '{}'", messageResolver.getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.addMessageResolver(messageResolver);
            }
        }
    }

    protected void removeMessageResolver(final IMessageResolver messageResolver) {
        synchronized (lock) {
            logger.debug("removing message resolver '{}'", messageResolver.getName());
            serviceTemplateEngine();
        }
    }

    protected void addDialect(final IDialect dialect) {
        synchronized (lock) {
            logger.debug("adding dialect '{}'", dialect.getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.addDialect(dialect);
            }
        }
    }

    protected void removeDialect(final IDialect dialect) {
        synchronized (lock) {
            logger.debug("removing dialect '{}'", dialect.getName());
            serviceTemplateEngine();
        }
    }

    protected void addLinkBuilder(final ILinkBuilder linkBuilder) {
        synchronized (lock) {
            logger.debug("adding link builder '{}'", linkBuilder.getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.addLinkBuilder(linkBuilder);
            }
        }
    }

    protected void removeLinkBuilder(final ILinkBuilder linkBuilder) {
        synchronized (lock) {
            logger.debug("removing link builder '{}'", linkBuilder.getName());
            serviceTemplateEngine();
        }
    }

    protected void setDecoupledTemplateLogicResolver(final IDecoupledTemplateLogicResolver decoupledTemplateLogicResolver) {
        synchronized (lock) {
            logger.debug("setting decoupled template logic resolver '{}'", decoupledTemplateLogicResolver.getClass().getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.setDecoupledTemplateLogicResolver(decoupledTemplateLogicResolver);
            }
        }
    }

    protected void unsetDecoupledTemplateLogicResolver(final IDecoupledTemplateLogicResolver decoupledTemplateLogicResolver) {
        synchronized (lock) {
            logger.debug("unsetting decoupled template logic resolver '{}'", decoupledTemplateLogicResolver.getClass().getName());
            serviceTemplateEngine();
        }
    }

    protected void setCacheManager(final ICacheManager cacheManager) {
        synchronized (lock) {
            logger.debug("setting cache manager '{}'", cacheManager.getClass().getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.setCacheManager(cacheManager);
            }
        }
    }

    protected void unsetCacheManager(final ICacheManager cacheManager) {
        synchronized (lock) {
            logger.debug("unsetting cache manager '{}'", cacheManager.getClass().getName());
            serviceTemplateEngine();
        }
    }

    protected void setEngineContextFactory(final IEngineContextFactory engineContextFactory) {
        synchronized (lock) {
            logger.debug("setting engine context factory '{}'", engineContextFactory.getClass().getName());
            if (templateEngine == null || templateEngine.isInitialized()) {
                serviceTemplateEngine();
            } else {
                templateEngine.setEngineContextFactory(engineContextFactory);
            }
        }
    }

    protected void unsetEngineContextFactory(final IEngineContextFactory engineContextFactory) {
        synchronized (lock) {
            logger.debug("unsetting engine context factory '{}'", engineContextFactory.getClass().getName());
            serviceTemplateEngine();
        }
    }

    @Activate
    private void activate(final ThymeleafScriptEngineFactoryConfiguration configuration, final BundleContext bundleContext) {
        logger.debug("activating");
        this.configuration = configuration;
        this.bundleContext = bundleContext;
        configure(configuration);
        setupTemplateEngine();
        registerTemplateEngine();
    }

    @Modified
    private void modified(final ThymeleafScriptEngineFactoryConfiguration configuration) {
        logger.debug("modifying");
        this.configuration = configuration;
        configure(configuration);
    }

    @Deactivate
    private void deactivate() {
        logger.debug("deactivating");
        unregisterTemplateEngine();
        templateEngine = null;
        bundleContext = null;
    }

    private void configure(final ThymeleafScriptEngineFactoryConfiguration configuration) {
        setExtensions(configuration.extensions());
        setMimeTypes(configuration.mimeTypes());
        setNames(configuration.names());
    }

    @Override
    public String getLanguageName() {
        return "Thymeleaf";
    }

    @Override
    public String getLanguageVersion() {
        try {
            final Properties properties = new Properties();
            properties.load(getClass().getResourceAsStream(THYMELEAF_PROPERTIES));
            return properties.getProperty("version");
        } catch (Exception e) {
            logger.error("error reading version from " + THYMELEAF_PROPERTIES, e);
            return ""; // null breaks output of web console
        }
    }

    @Override
    public ScriptEngine getScriptEngine() {
        logger.debug("getting script engine for Thymeleaf");
        return new ThymeleafScriptEngine(this);
    }

    private void serviceTemplateEngine() {
        unregisterTemplateEngine();
        setupTemplateEngine();
        registerTemplateEngine();
    }

    private void setupTemplateEngine() {
        logger.info("setting up new template engine");
        templateEngine = null;
        if (configuration == null) {
            logger.info("configuration is null, not setting up new template engine");
            return;
        }

        if (!configuration.useStandardEngineContextFactory() && engineContextFactory == null) {
            logger.info("no engine context factory available, not setting up new template engine");
            return;
        }

        // setup template engine
        final TemplateEngine templateEngine = new TemplateEngine();
        // Template Resolvers
        if (this.templateResolvers != null) {
            final Set<ITemplateResolver> templateResolvers = new HashSet<>(this.templateResolvers);
            templateEngine.setTemplateResolvers(templateResolvers);
        }
        // Message Resolvers
        if (this.messageResolvers != null) {
            final Set<IMessageResolver> messageResolvers = new HashSet<>(this.messageResolvers);
            templateEngine.setMessageResolvers(messageResolvers);
        }
        if (configuration.useStandardMessageResolver()) {
            final IMessageResolver standardMessageResolver = new StandardMessageResolver();
            templateEngine.addMessageResolver(standardMessageResolver);
        }
        // Link Builders
        if (this.linkBuilders != null) {
            final Set<ILinkBuilder> linkBuilders = new HashSet<>(this.linkBuilders);
            templateEngine.setLinkBuilders(linkBuilders);
        }
        if (configuration.useStandardLinkBuilder()) {
            final ILinkBuilder standardLinkBuilder = new StandardLinkBuilder();
            templateEngine.addLinkBuilder(standardLinkBuilder);
        }
        // Dialects
        if (this.dialects != null) {
            final Set<IDialect> dialects = new HashSet<>(this.dialects);
            templateEngine.setDialects(dialects);
        }
        if (configuration.useStandardDialect()) {
            final IDialect standardDialect = new StandardDialect();
            templateEngine.addDialect(standardDialect);
        }
        // Decoupled Template Logic Resolver
        if (!configuration.useStandardDecoupledTemplateLogicResolver()) {
            templateEngine.setDecoupledTemplateLogicResolver(decoupledTemplateLogicResolver);
        }
        // Cache Manager
        if (!configuration.useStandardCacheManager()) {
            templateEngine.setCacheManager(cacheManager);
        }
        // Engine Context Factory
        if (!configuration.useStandardEngineContextFactory()) {
            templateEngine.setEngineContextFactory(engineContextFactory);
        }
        //
        this.templateEngine = templateEngine;
    }

    private void registerTemplateEngine() {
        if (templateEngine == null || templateEngine.getTemplateResolvers().size() == 0 || templateEngine.getMessageResolvers().size() == 0 || templateEngine.getDialects().size() == 0) {
            return;
        }
        final Dictionary<String, String> properties = new Hashtable<>();
        properties.put(Constants.SERVICE_DESCRIPTION, "Thymeleaf TemplateEngine");
        properties.put(Constants.SERVICE_VENDOR, "The Thymeleaf Team");
        logger.info("registering {} as service {} with properties {}", templateEngine, ITemplateEngine.class.getName(), properties);
        serviceRegistration = bundleContext.registerService(ITemplateEngine.class, templateEngine, properties);
    }

    private void unregisterTemplateEngine() {
        if (serviceRegistration != null) {
            serviceRegistration.unregister();
            serviceRegistration = null;
        }
    }

    TemplateEngine getTemplateEngine() {
        synchronized (lock) {
            if (templateEngine == null) {
                serviceTemplateEngine();
            }
            return templateEngine;
        }
    }

    ResourceResolver getRequestScopedResourceResolver() {
        return scriptingResourceResolverProvider.getRequestScopedResourceResolver();
    }

    ServletContext getSlingServletContext() {
        return servletContext;
    }

}
