/*
 * Copyright (C) 2011 The Guava Authors
 *
 * 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.common.cache;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.Maps;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.Nullable;

/**
 * Utility {@link CacheLoader} implementations intended for use in testing.
 *
 * @author mike nonemacher
 */
@GwtCompatible(emulated = true)
class TestingCacheLoaders {

  /**
   * Returns a {@link CacheLoader} that implements a naive {@link CacheLoader#loadAll}, delegating
   * {@link CacheLoader#load} calls to {@code loader}.
   */
  static <K, V> CacheLoader<K, V> bulkLoader(final CacheLoader<K, V> loader) {
    checkNotNull(loader);
    return new CacheLoader<K, V>() {
      @Override
      public V load(K key) throws Exception {
        return loader.load(key);
      }

      @Override
      public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception {
        Map<K, V> result = Maps.newHashMap(); // allow nulls
        for (K key : keys) {
          result.put(key, load(key));
        }
        return result;
      }
    };
  }

  /**
   * Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
   */
  static <K, V> ConstantLoader<K, V> constantLoader(@Nullable V constant) {
    return new ConstantLoader<K, V>(constant);
  }

  /**
   * Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
   */
  static IncrementingLoader incrementingLoader() {
    return new IncrementingLoader();
  }

  /**
   * Returns a {@link CacheLoader} that throws the given error for every request.
   */
  static <K, V> CacheLoader<K, V> errorLoader(final Error e) {
    checkNotNull(e);
    return new CacheLoader<K, V>() {
      @Override
      public V load(K key) {
        throw e;
      }
    };
  }

  /**
   * Returns a {@link CacheLoader} that throws the given exception for every request.
   */
  static <K, V> CacheLoader<K, V> exceptionLoader(final Exception e) {
    checkNotNull(e);
    return new CacheLoader<K, V>() {
      @Override
      public V load(K key) throws Exception {
        throw e;
      }
    };
  }

  /**
   * Returns a {@link CacheLoader} that returns the key for every request.
   */
  static <T> IdentityLoader<T> identityLoader() {
    return new IdentityLoader<T>();
  }

  /**
   * Returns a {@code new Object()} for every request, and increments a counter for every request.
   * The count is accessible via {@link #getCount}.
   */
  static class CountingLoader extends CacheLoader<Object, Object> {
    private final AtomicInteger count = new AtomicInteger();

    @Override
    public Object load(Object from) {
      count.incrementAndGet();
      return new Object();
    }

    public int getCount() {
      return count.get();
    }
  }

  static final class ConstantLoader<K, V> extends CacheLoader<K, V> {
    private final V constant;

    ConstantLoader(V constant) {
      this.constant = constant;
    }

    @Override
    public V load(K key) {
      return constant;
    }
  }

  /**
   * Returns a {@code new Object()} for every request, and increments a counter for every request.
   * An {@code Integer} loader that returns the key for {@code load} requests, and increments the
   * old value on {@code reload} requests. The load counts are accessible via {@link #getLoadCount}
   * and {@link #getReloadCount}.
   */
  static class IncrementingLoader extends CacheLoader<Integer, Integer> {
    private final AtomicInteger countLoad = new AtomicInteger();
    private final AtomicInteger countReload = new AtomicInteger();

    @Override
    public Integer load(Integer key) {
      countLoad.incrementAndGet();
      return key;
    }

    public int getLoadCount() {
      return countLoad.get();
    }

    public int getReloadCount() {
      return countReload.get();
    }
  }

  static final class IdentityLoader<T> extends CacheLoader<T, T> {
    @Override
    public T load(T key) {
      return key;
    }
  }
}

