/*
 * 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.myfaces.extensions.cdi.core.impl.scope.conversation;

import org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig;
import org.apache.myfaces.extensions.cdi.core.api.config.view.DefaultErrorView;
import org.apache.myfaces.extensions.cdi.core.api.provider.BeanManagerProvider;
import org.apache.myfaces.extensions.cdi.core.api.security.AccessDeniedException;
import org.apache.myfaces.extensions.cdi.core.api.security.event.InvalidBeanCreationEvent;
import org.apache.myfaces.extensions.cdi.core.api.security.SecurityViolation;
import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.PassivationCapable;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

/**
 * Adapter for all CODI conversation scopes
 */
public class ConversationContextAdapter implements Context
{
    private final Class<? extends Annotation> scopeType;
    private final AbstractGroupedConversationContext conversationContext;
    private BeanManager beanManager;
    private Boolean invalidBeanCreationEventEnabled;

    /**
     * Constructor which allows to build a context for conversations for the given scope-type and scope-implementation
     * @param scope type of the scope
     * @param conversationContext implementation of the conversation scope
     * @param beanManager current bean-manager
     */
    public ConversationContextAdapter(Class<? extends Annotation> scope,
                                      AbstractGroupedConversationContext conversationContext,
                                      BeanManager beanManager)
    {
        this.scopeType = scope;
        this.conversationContext = conversationContext;
        this.beanManager = beanManager;
    }

    /** {@inheritDoc} */
    public Class<? extends Annotation> getScope()
    {
        return this.scopeType;
    }

    /**
     * @param component         descriptor of the bean
     * @param creationalContext context for creating a bean
     * @return a scoped bean-instance
     */
    public <T> T get(Contextual<T> component, CreationalContext<T> creationalContext)
    {
        if (component instanceof PassivationCapable && !(component instanceof Bean))
        {
            component = (Contextual<T>) BeanManagerProvider.getInstance().getBeanManager()
                .getPassivationCapableBean(((PassivationCapable) component).getId());
        }

        if (component instanceof Bean)
        {
            //since the basic use-case is related to topics like security,
            //we only have to check it at the very first access - everything else would have a major performance impact
            checkForInvalidBeanAccess((Bean<T>)component);

            //cdi doesn't support to throw an exception -> create the bean in any case - codi has to handle the rest
            return this.conversationContext.create((Bean<T>)component, creationalContext);
        }

        Class invalidComponentClass = component.create(creationalContext).getClass();
        throw new IllegalStateException(invalidComponentClass + " is no valid conversation scoped bean");
    }

    /**
     * @param component descriptor of the bean
     * @return an instance of the requested bean if it already exists in the current
     *         {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext}
     *         null otherwise
     */
    public <T> T get(Contextual<T> component)
    {
        //workaround for openejb - see EXTCDI-304
        if (component == null)
        {
            return null;
        }

        if (component instanceof PassivationCapable && !(component instanceof Bean))
        {
            component = (Contextual<T>) BeanManagerProvider.getInstance().getBeanManager()
                .getPassivationCapableBean(((PassivationCapable) component).getId());
        }

        if (component instanceof Bean)
        {
            return this.conversationContext.resolve((Bean<T>)component);
        }
        throw new IllegalStateException(component.getClass() + " is no valid conversation scoped bean");
    }

    /** {@inheritDoc} */
    public boolean isActive()
    {
        return this.conversationContext.isActive();
    }

    private <T> void checkForInvalidBeanAccess(Bean<T> bean)
    {
        lazyInit();

        if(!this.invalidBeanCreationEventEnabled)
        {
            return;
        }
        
        Set<SecurityViolation> violations = this.conversationContext.checkPermission(bean);
        Set<SecurityViolation> violationsToThrow = new HashSet<SecurityViolation>();

        for(SecurityViolation securityViolation : violations)
        {
            InvalidBeanCreationEvent invalidBeanCreationEvent = new InvalidBeanCreationEvent(securityViolation);
            this.beanManager.fireEvent(invalidBeanCreationEvent);

            if(invalidBeanCreationEvent.isThrowSecurityViolation())
            {
                violationsToThrow.add(securityViolation);
            }
        }

        if(!violationsToThrow.isEmpty())
        {
            throw new AccessDeniedException(violationsToThrow, DefaultErrorView.class);
        }
    }

    private void lazyInit()
    {
        if(this.invalidBeanCreationEventEnabled == null)
        {
            init();
        }
    }

    private synchronized void init()
    {
        // switch into paranoia mode
        if(this.invalidBeanCreationEventEnabled == null)
        {
            CodiCoreConfig codiCoreConfig =
                    CodiUtils.getContextualReferenceByClass(this.beanManager, CodiCoreConfig.class);

            this.invalidBeanCreationEventEnabled = codiCoreConfig.isInvalidBeanCreationEventEnabled();
        }
    }
}
