// Copyright (C) 2012 The Android Open Source Project
//
// 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 com.google.gerrit.server.util;

import com.google.inject.OutOfScopeException;
import com.google.inject.Scope;

import java.util.concurrent.Callable;

/**
 * {@link RequestScopePropagator} implementation for request scopes based on
 * a {@link ThreadLocal} context.
 *
 * @param <C> "context" type stored in the {@link ThreadLocal}.
 */
public abstract class ThreadLocalRequestScopePropagator<C>
    extends RequestScopePropagator {

  private final ThreadLocal<C> threadLocal;

  protected ThreadLocalRequestScopePropagator(Scope scope,
      ThreadLocal<C> threadLocal, ThreadLocalRequestContext local) {
    super(scope, local);
    this.threadLocal = threadLocal;
  }

  /**
   * @see RequestScopePropagator#wrap(Callable)
   */
  @Override
  protected final <T> Callable<T> wrapImpl(final Callable<T> callable) {
    final C ctx = continuingContext(requireContext());
    return new Callable<T>() {
      @Override
      public T call() throws Exception {
        C old = threadLocal.get();
        threadLocal.set(ctx);
        try {
          return callable.call();
        } finally {
          if (old != null) {
            threadLocal.set(old);
          } else {
            threadLocal.remove();
          }
        }
      }
    };
  }

  private C requireContext() {
    C context = threadLocal.get();
    if (context == null) {
      throw new OutOfScopeException("Cannot access scoped object");
    }
    return context;
  }

  /**
   * Returns a new context object based on the passed in context that has no
   * request scoped objects initialized.
   * <p>
   * Note that some code paths expect request-scoped objects like
   * {@code CurrentUser} to be constructible starting from just the context
   * object returned by this method. For example, in the SSH scope, the context
   * includes the {@code SshSession}, which is used by
   * {@code SshCurrentUserProvider} to construct a new {@code CurrentUser} in
   * the new thread.
   *
   * @param ctx the context to continue.
   * @return a new context.
   */
  protected abstract C continuingContext(C ctx);
}
