// 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.common.collect.Maps;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.RemotePeer;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.servlet.ServletScopes;
import com.google.inject.util.Providers;
import com.google.inject.util.Types;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.Callable;

import javax.annotation.Nullable;

/** Propagator for Guice's built-in servlet scope. */
public class GuiceRequestScopePropagator extends RequestScopePropagator {

  private final String url;
  private final SocketAddress peer;
  private final CurrentUser user;

  @Inject
  GuiceRequestScopePropagator(
      @CanonicalWebUrl @Nullable Provider<String> urlProvider,
      @RemotePeer Provider<SocketAddress> remotePeerProvider,
      Provider<CurrentUser> currentUserProvider) {
    super(ServletScopes.REQUEST);
    this.url = urlProvider != null ? urlProvider.get() : null;
    this.peer = remotePeerProvider.get();
    this.user = currentUserProvider.get();
  }

  /**
   * @see RequestScopePropagator#wrap(Callable)
   */
  @Override
  protected <T> Callable<T> wrapImpl(Callable<T> callable) {
    Map<Key<?>, Object> seedMap = Maps.newHashMap();

    // Request scopes appear to use specific keys in their map, instead of only
    // providers. Add bindings for both the key to the instance directly and the
    // provider to the instance to be safe.
    seedMap.put(Key.get(typeOfProvider(String.class), CanonicalWebUrl.class),
        Providers.of(url));
    seedMap.put(Key.get(String.class, CanonicalWebUrl.class), url);

    seedMap.put(Key.get(typeOfProvider(SocketAddress.class), RemotePeer.class),
        Providers.of(peer));
    seedMap.put(Key.get(SocketAddress.class, RemotePeer.class), peer);

    seedMap.put(Key.get(typeOfProvider(CurrentUser.class)), Providers.of(user));
    seedMap.put(Key.get(CurrentUser.class), user);

    return ServletScopes.continueRequest(callable, seedMap);
  }

  private ParameterizedType typeOfProvider(Type type) {
    return Types.newParameterizedType(Provider.class, type);
  }
}
