package com.atlassian.stash.internal.plugin;

import com.atlassian.plugin.module.ModuleFactory;
import com.atlassian.plugin.webresource.WebResourceIntegration;
import com.atlassian.plugin.webresource.transformer.WebResourceTransformer;
import com.atlassian.plugin.webresource.transformer.WebResourceTransformerModuleDescriptor;
import com.atlassian.bitbucket.request.RequestManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Conventions;

import javax.servlet.http.HttpServletRequest;

/**
 * RequestCachingWebResourceTransformerModuleDescriptor caches WebResourceTransformer modules created within the current
 * HTTP request.
 *
 * This cannot be pushed into plugins, unfortunately, as there isn't a cross product way of getting the current HTTP
 * request.
 *
 * Alternatively, we can make the plugin system less brain dead with respect to creation of WebResourceTransformers. It
 * would help if they didn't specify that instances of WebResourceTransformer are created per request.
 */
public class RequestCachingWebResourceTransformerModuleDescriptor extends WebResourceTransformerModuleDescriptor {

    // Don't use HttpContext here; if we do, startup will get blocked on OSGI loading of the HttpContext provided by
    // the SAL plugin
    private final RequestManager requestManager;

    @Autowired
    public RequestCachingWebResourceTransformerModuleDescriptor(RequestManager requestManager,
                                                                WebResourceIntegration webResourceIntegration,
                                                                ModuleFactory moduleFactory) {
        super(moduleFactory, webResourceIntegration);

        this.requestManager = requestManager;
    }

    @Override
    public WebResourceTransformer getModule() {
        String moduleAttributeName = Conventions.getQualifiedAttributeName(
                RequestCachingWebResourceTransformerModuleDescriptor.class, moduleClass.toString());
        HttpServletRequest request = getRequest();

        WebResourceTransformer module = (WebResourceTransformer) request.getAttribute(moduleAttributeName);
        if (module == null) {
            module = (WebResourceTransformer) super.getModule();
            request.setAttribute(moduleAttributeName, module);
        }

        return module;
    }

    private HttpServletRequest getRequest() {
        return (HttpServletRequest) requestManager.getRequestContext().getRawRequest();
    }
}
