/*
 * JBoss, Home of Professional Open Source
 * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed 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.jboss.weld.integration.ejb.interceptor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.enterprise.inject.spi.InterceptionType;
import javax.enterprise.inject.spi.Interceptor;
import javax.interceptor.InvocationContext;

public class DelegatingInterceptorInvocationContext implements InvocationContext
{

   private InvocationContext delegateInvocationContext;

   private Queue<Interceptor> invocationQueue;
   private Queue<Object> interceptorInstances;

   private InterceptionType interceptionType;

   public DelegatingInterceptorInvocationContext(InvocationContext delegateInvocationContext, List<Interceptor<?>> interceptors, List<Object> instances, InterceptionType interceptionType)
   {
      this.delegateInvocationContext = delegateInvocationContext;
      this.interceptionType = interceptionType;
      this.invocationQueue = new ConcurrentLinkedQueue<Interceptor>(interceptors);
      this.interceptorInstances = new ConcurrentLinkedQueue<Object>(instances);
   }

   public Map<String, Object> getContextData()
   {
      return delegateInvocationContext.getContextData();
   }

   public Method getMethod()
   {
      return delegateInvocationContext.getMethod();
   }

   public Object[] getParameters()
   {
      return delegateInvocationContext.getParameters();
   }

   public Object getTarget()
   {
      return delegateInvocationContext.getTarget();
   }

   public Object proceed() throws Exception
   {
      if (!invocationQueue.isEmpty())
      {
         return invocationQueue.remove().intercept(interceptionType, interceptorInstances.remove(), this);
      }
      else
      {
         return delegateInvocationContext.proceed();
      }
   }

   public void setParameters(Object[] params)
   {
      delegateInvocationContext.setParameters(params);
   }

   public Object getTimer()
   {
      throw new UnsupportedOperationException("Get timer not supported");
   }
}