// Copyright (C) 2009 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.cache;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.google.inject.util.Types;

import java.io.Serializable;
import java.lang.reflect.Type;

/**
 * Miniature DSL to support binding {@link Cache} instances in Guice.
 */
public abstract class CacheModule extends AbstractModule {
  private static final TypeLiteral<Cache<?, ?>> ANY_CACHE =
      new TypeLiteral<Cache<?, ?>>() {};

  /**
   * Declare a named in-memory cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K, V> CacheBinding<K, V> cache(
      String name,
      Class<K> keyType,
      Class<V> valType) {
    return cache(name, TypeLiteral.get(keyType), TypeLiteral.get(valType));
  }

  /**
   * Declare a named in-memory cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K, V> CacheBinding<K, V> cache(
      String name,
      Class<K> keyType,
      TypeLiteral<V> valType) {
    return cache(name, TypeLiteral.get(keyType), valType);
  }

  /**
   * Declare a named in-memory cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K, V> CacheBinding<K, V> cache(
      String name,
      TypeLiteral<K> keyType,
      TypeLiteral<V> valType) {
    Type type = Types.newParameterizedType(
        Cache.class,
        keyType.getType(), valType.getType());

    @SuppressWarnings("unchecked")
    Key<Cache<K, V>> key = (Key<Cache<K, V>>) Key.get(type, Names.named(name));

    CacheProvider<K, V> m =
        new CacheProvider<K, V>(this, name, keyType, valType);
    bind(key).toProvider(m).in(Scopes.SINGLETON);
    bind(ANY_CACHE).annotatedWith(Exports.named(name)).to(key);
    return m.maximumWeight(1024);
  }

  <K,V> Provider<CacheLoader<K,V>> bindCacheLoader(
      CacheProvider<K, V> m,
      Class<? extends CacheLoader<K,V>> impl) {
    Type type = Types.newParameterizedType(
        Cache.class,
        m.keyType().getType(), m.valueType().getType());

    Type loadingType = Types.newParameterizedType(
        LoadingCache.class,
        m.keyType().getType(), m.valueType().getType());

    Type loaderType = Types.newParameterizedType(
        CacheLoader.class,
        m.keyType().getType(), m.valueType().getType());

    @SuppressWarnings("unchecked")
    Key<LoadingCache<K, V>> key =
        (Key<LoadingCache<K, V>>) Key.get(type, Names.named(m.name));

    @SuppressWarnings("unchecked")
    Key<LoadingCache<K, V>> loadingKey =
        (Key<LoadingCache<K, V>>) Key.get(loadingType, Names.named(m.name));

    @SuppressWarnings("unchecked")
    Key<CacheLoader<K, V>> loaderKey =
        (Key<CacheLoader<K, V>>) Key.get(loaderType, Names.named(m.name));

    bind(loaderKey).to(impl).in(Scopes.SINGLETON);
    bind(loadingKey).to(key);
    return getProvider(loaderKey);
  }

  <K,V> Provider<Weigher<K,V>> bindWeigher(
      CacheProvider<K, V> m,
      Class<? extends Weigher<K,V>> impl) {
    Type weigherType = Types.newParameterizedType(
        Weigher.class,
        m.keyType().getType(), m.valueType().getType());

    @SuppressWarnings("unchecked")
    Key<Weigher<K, V>> key =
        (Key<Weigher<K, V>>) Key.get(weigherType, Names.named(m.name));

    bind(key).to(impl).in(Scopes.SINGLETON);
    return getProvider(key);
  }

  /**
   * Declare a named in-memory/on-disk cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K extends Serializable, V extends Serializable> CacheBinding<K, V> persist(
      String name,
      Class<K> keyType,
      Class<V> valType) {
    return persist(name, TypeLiteral.get(keyType), TypeLiteral.get(valType));
  }

  /**
   * Declare a named in-memory/on-disk cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K extends Serializable, V extends Serializable> CacheBinding<K, V> persist(
      String name,
      Class<K> keyType,
      TypeLiteral<V> valType) {
    return persist(name, TypeLiteral.get(keyType), valType);
  }

  /**
   * Declare a named in-memory/on-disk cache.
   *
   * @param <K> type of key used to lookup entries.
   * @param <V> type of value stored by the cache.
   * @return binding to describe the cache.
   */
  protected <K extends Serializable, V extends Serializable> CacheBinding<K, V> persist(
      String name,
      TypeLiteral<K> keyType,
      TypeLiteral<V> valType) {
    return ((CacheProvider<K, V>) cache(name, keyType, valType))
        .persist(true);
  }
}
