/**
 * Copyright (C) 2006 Google Inc.
 *
 * 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.inject.util;

import static com.google.inject.util.ReferenceType.SOFT;
import static com.google.inject.util.ReferenceType.STRONG;
import static com.google.inject.util.ReferenceType.WEAK;

import junit.framework.TestCase;

import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author crazybob@google.com (Bob Lee)
 */
public class ReferenceCacheTest extends TestCase {

  public void testCancellation() {
    final AtomicInteger count = new AtomicInteger();

    final ReferenceCache rc = new ReferenceCache() {
      protected Object create(Object key) {
        try {
          cancel();
          Thread.sleep(10);
          return null;
        } catch (InterruptedException e) {
          throw new RuntimeException(e);
        }
      }
    };

    Thread[] threads = new Thread[3];
    for (int i = 0; i < 3; i++) {
      threads[i] = new Thread() {
        public void run() {
          try {
            rc.get("foo");
            fail();
          } catch (CancellationException e) {
            count.incrementAndGet();
          }
        }
      };
    }
    for (int i = 0; i < 3; i++) {
      threads[i].start();
    }
    for (int i = 0; i < 3; i++) {
      try {
        threads[i].join();
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }

    assertEquals(threads.length, count.get());
  }

  public void testApply() {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        WEAK, WEAK, new SomeFunction());
    assertEquals(Integer.valueOf(1), cache.get("foo"));
    assertEquals(Integer.valueOf(1), cache.get("foo"));
    assertEquals(Integer.valueOf(2), cache.get("bar"));
    assertEquals(Integer.valueOf(1), cache.get("foo"));
    assertEquals(Integer.valueOf(3), cache.get("baz"));
  }

  public void testSleepConcurrency() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        WEAK, WEAK, new SleepFunction());
    assertConcurrency(cache, false);
  }

  public void testBusyConcurrency() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        WEAK, WEAK, new BusyFunction());
    assertConcurrency(cache, false);
  }

  public void testFastConcurrency() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        WEAK, WEAK, new SomeFunction());
    assertConcurrency(cache, false);
  }

  public void testSleepCanonical() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        STRONG, SOFT, new SleepFunction());
    assertConcurrency(cache, true);
  }

  public void testBusyCanonical() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        STRONG, SOFT, new BusyFunction());
    assertConcurrency(cache, true);
  }

  public void testFastCanonical() throws InterruptedException {
    ReferenceMap<String, Integer> cache = ReferenceCache.of(
        STRONG, SOFT, new SomeFunction());
    assertConcurrency(cache, true);
  }

  private static void assertConcurrency(
      final ReferenceMap<String, Integer> cache,
      final boolean simulateAliasing) throws InterruptedException {
    final int n = 20;
    final CountDownLatch startSignal = new CountDownLatch(1);
    final CountDownLatch doneSignal = new CountDownLatch(n);
    for (int i = 0; i < n; i++) {
      new Thread() {
        public void run() {
          try {
            startSignal.await();
            for (int j = 0; j < n; j++) {
              cache.get(simulateAliasing ? new String("foo") : "foo");
            }
            doneSignal.countDown();
          } catch (InterruptedException ignored) {}
        }
      }.start();
    }

    startSignal.countDown();
    doneSignal.await();
    assertEquals(Integer.valueOf(1), cache.get("foo"));
    assertEquals(Integer.valueOf(2), cache.get("bar"));
  }

  private static class SomeFunction implements Function<String, Integer> {
    private int numApplies = 0;
    public Integer apply(String s) {
      return ++numApplies;
    }
  }

  private static class SleepFunction implements Function<String, Integer> {
    private int numApplies = 0;
    public Integer apply(String s) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
      return ++numApplies;
    }
  }

  private static class BusyFunction implements Function<String, Integer> {
    private int numApplies = 0;
    public Integer apply(String s) {
      for (int i = 0; i < 1000; i++) {
        Math.sqrt(i);
      }
      return ++numApplies;
    }
  }
}
