/*
 *     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.server.cxf.rs;

import org.apache.cxf.jaxrs.ext.ContextProvider;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.openejb.cdi.CdiAppContextsService;
import org.apache.openejb.rest.ThreadLocalContextManager;
import org.apache.openejb.threads.task.CUTask;

import javax.annotation.Resource;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.enterprise.concurrent.ManagedTaskListener;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Providers;
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseEventSink;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;

public final class Contexts {
    private static final ThreadLocal<Exchange> EXCHANGE = new ThreadLocal<>();
    private static final Set<Class<?>> CONTEXT_CLASSES = contextClasses();

    private Contexts() {
        // no-op
    }

    public static Collection<Class<?>> findContextFields(final Class<?> cls, final Collection<Class<?>> types) {
        if (cls == Object.class || cls == null) {
            return Collections.emptyList();
        }
        for (final Field f : cls.getDeclaredFields()) {
            for (final Annotation a : f.getAnnotations()) {
                if (a.annotationType() == Context.class || a.annotationType() == Resource.class
                    && isContextClass(f.getType())) {
                    types.add(f.getType());
                }
            }
        }
        findContextFields(cls.getSuperclass(), types);
        return types;
    }

    private static boolean isContextClass(final Class<?> type) {
        return CONTEXT_CLASSES.contains(type);
    }

    private static Set<Class<?>> contextClasses() {
        final Set<Class<?>> classes = new HashSet<>(); classes.add(UriInfo.class);
        classes.add(SecurityContext.class);
        classes.add(HttpHeaders.class);
        classes.add(ContextResolver.class);
        classes.add(Providers.class);
        classes.add(Request.class);
        /* TODO: when we have jaxrs 2
        classes.add(ResourceInfo.class);
        classes.add(ResourceContext.class);
        */
        classes.add(Application.class);
        classes.add(HttpServletRequest.class);
        classes.add(HttpServletResponse.class);
        classes.add(ServletConfig.class);
        classes.add(ServletContext.class);
        classes.add(MessageContext.class);
        classes.add(Sse.class);
        classes.add(SseEventSink.class);

        return classes;
    }

    @SuppressWarnings("UnusedDeclaration")
    public static void bind(final Exchange exchange) {
        if (exchange == null) {
            return;
        }

        final ClassResourceInfo cri = exchange.get(OperationResourceInfo.class).getClassResourceInfo();

        // binding context fields
        final Set<Class<?>> types = new HashSet<>();
        for (final Field field : cri.getContextFields()) {
            types.add(field.getType());
        }

        bind(exchange, types);
    }

    /**
     * Using a set ensures we don't set the thread local twice or more,
     * there may be super classes with injection points of identical types
     *
     * Also allows us to get context references from other sources such as interceptors
     *
     * @param exchange Exchange
     * @param types    Collection
     */
    public static void bind(final Exchange exchange, final Collection<Class<?>> types) {
        EXCHANGE.set(exchange); // used in lazy mode by RESTResourceFinder if cdi beans uses @Context, === initThreadLocal
        CdiAppContextsService.pushRequestReleasable(CleanUpThreadLocal.INSTANCE);

        for (final Class<?> type : types) {
            if (Request.class.equals(type)) {
                final Request binding = JAXRSUtils.createContextValue(exchange.getInMessage(), null, Request.class);
                ThreadLocalContextManager.REQUEST.set(binding);
            } else if (UriInfo.class.equals(type)) {
                final UriInfo binding = JAXRSUtils.createContextValue(exchange.getInMessage(), null, UriInfo.class);
                ThreadLocalContextManager.URI_INFO.set(binding);
            } else if (HttpHeaders.class.equals(type)) {
                final HttpHeaders binding = JAXRSUtils.createContextValue(exchange.getInMessage(), null, HttpHeaders.class);
                ThreadLocalContextManager.HTTP_HEADERS.set(binding);
            } else if (SecurityContext.class.equals(type)) {
                final SecurityContext binding = JAXRSUtils.createContextValue(exchange.getInMessage(), null, SecurityContext.class);
                ThreadLocalContextManager.SECURITY_CONTEXT.set(binding);
            } else if (ContextResolver.class.equals(type)) {
                final ContextResolver<?> binding = JAXRSUtils.createContextValue(exchange.getInMessage(), type, ContextResolver.class);
                ThreadLocalContextManager.CONTEXT_RESOLVER.set(binding);
            } else if (Providers.class.equals(type)) {
                final Providers providers = JAXRSUtils.createContextValue(exchange.getInMessage(), null, Providers.class);
                ThreadLocalContextManager.PROVIDERS.set(providers);
            } else if (ServletRequest.class.equals(type)) {
                ServletRequest servletRequest = JAXRSUtils.createContextValue(exchange.getInMessage(), null, ServletRequest.class);
                if (servletRequest == null) { // probably the case with CXF
                    servletRequest = JAXRSUtils.createContextValue(exchange.getInMessage(), null, HttpServletRequest.class);
                }
                ThreadLocalContextManager.SERVLET_REQUEST.set(servletRequest);
            } else if (HttpServletRequest.class.equals(type)) {
                final HttpServletRequest httpServletRequest = JAXRSUtils.createContextValue(exchange.getInMessage(), null, HttpServletRequest.class);
                ThreadLocalContextManager.HTTP_SERVLET_REQUEST.set(httpServletRequest);
            } else if (HttpServletResponse.class.equals(type)) {
                final HttpServletResponse httpServletResponse = JAXRSUtils.createContextValue(exchange.getInMessage(), null, HttpServletResponse.class);
                ThreadLocalContextManager.HTTP_SERVLET_RESPONSE.set(httpServletResponse);
            } else if (ServletConfig.class.equals(type)) {
                final ServletConfig servletConfig = JAXRSUtils.createContextValue(exchange.getInMessage(), null, ServletConfig.class);
                ThreadLocalContextManager.SERVLET_CONFIG.set(servletConfig);
            } else if (Configuration.class.equals(type)) {
                final Configuration config = JAXRSUtils.createContextValue(exchange.getInMessage(), null, Configuration.class);
                ThreadLocalContextManager.CONFIGURATION.set(config);
            } else if (ResourceInfo.class.equals(type)) {
                final ResourceInfo config = JAXRSUtils.createContextValue(exchange.getInMessage(), null, ResourceInfo.class);
                ThreadLocalContextManager.RESOURCE_INFO.set(config);
            } else if (ResourceContext.class.equals(type)) {
                final ResourceContext config = JAXRSUtils.createContextValue(exchange.getInMessage(), null, ResourceContext.class);
                ThreadLocalContextManager.RESOURCE_CONTEXT.set(config);
            } else if (Application.class.equals(type)) {
                final Application config = JAXRSUtils.createContextValue(exchange.getInMessage(), null, Application.class);
                ThreadLocalContextManager.APPLICATION.set(config);
            } else {
                final Message message = exchange.getInMessage();
                final ContextProvider<?> provider = ProviderFactory.getInstance(message).createContextProvider(type, message);
                if (provider != null) {
                    final Object value = provider.createContext(message);
                    Map<String, Object> map = ThreadLocalContextManager.OTHERS.get();
                    if (map == null) {
                        map = new HashMap<>();
                        ThreadLocalContextManager.OTHERS.set(map);
                    }
                    map.put(type.getName(), value);
                }
            }
        }
    }

    public static <T> T find(final Class<T> clazz) {
        final Message m = JAXRSUtils.getCurrentMessage();
        if (m  != null) {
            return JAXRSUtils.createContextValue(m, null, clazz);
        }
        final Exchange exchange = EXCHANGE.get();
        if (exchange == null) {
            throw new IllegalStateException("No CXF message usable for JAX-RS @Context injections in that thread so can't use " + clazz);
        }
        return JAXRSUtils.createContextValue(exchange.getInMessage(), null, clazz);
    }

    public static Object state() {
        return EXCHANGE.get();
    }

    public static Object restore(final Object oldState) {
        final Object old = state();
        EXCHANGE.set(Exchange.class.cast(oldState));
        return old;
    }

    private static class CleanUpThreadLocal implements Runnable {
        public static final Runnable INSTANCE = new CleanUpThreadLocal();

        @Override
        public void run() {
            EXCHANGE.remove();
            ThreadLocalContextManager.reset();
        }
    }
}
