/*
 * 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.cache.CacheBuilderSpec.parse;
import static com.google.common.cache.TestingWeighers.constantWeigher;

import com.google.common.base.Suppliers;
import com.google.common.cache.LocalCache.Strength;
import com.google.common.testing.EqualsTester;

import junit.framework.TestCase;

import java.util.concurrent.TimeUnit;

/**
 * Tests CacheBuilderSpec.
 * TODO(user): tests of a few invalid input conditions, boundary conditions.
 *
 * @author Adam Winer
 */
public class CacheBuilderSpecTest extends TestCase {
  public void testParse_empty() {
    CacheBuilderSpec spec = parse("");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(CacheBuilder.newBuilder(), CacheBuilder.from(spec));
  }

  public void testParse_initialCapacity() {
    CacheBuilderSpec spec = parse("initialCapacity=10");
    assertEquals(10, spec.initialCapacity.intValue());
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().initialCapacity(10), CacheBuilder.from(spec));
  }

  public void testParse_initialCapacityRepeated() {
    try {
      parse("initialCapacity=10, initialCapacity=20");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_maximumSize() {
    CacheBuilderSpec spec = parse("maximumSize=9000");
    assertNull(spec.initialCapacity);
    assertEquals(9000, spec.maximumSize.longValue());
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().maximumSize(9000), CacheBuilder.from(spec));
  }

  public void testParse_maximumSizeRepeated() {
    try {
      parse("maximumSize=10, maximumSize=20");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_maximumWeight() {
    CacheBuilderSpec spec = parse("maximumWeight=9000");
    assertNull(spec.initialCapacity);
    assertEquals(9000, spec.maximumWeight.longValue());
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().maximumWeight(9000), CacheBuilder.from(spec));
  }

  public void testParse_maximumWeightRepeated() {
    try {
      parse("maximumWeight=10, maximumWeight=20");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_maximumSizeAndMaximumWeight() {
    try {
      parse("maximumSize=10, maximumWeight=20");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_concurrencyLevel() {
    CacheBuilderSpec spec = parse("concurrencyLevel=32");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertEquals(32, spec.concurrencyLevel.intValue());
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().concurrencyLevel(32), CacheBuilder.from(spec));
  }

  public void testParse_concurrencyLevelRepeated() {
    try {
      parse("concurrencyLevel=10, concurrencyLevel=20");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_weakKeys() {
    CacheBuilderSpec spec = parse("weakKeys");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertEquals(Strength.WEAK, spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().weakKeys(), CacheBuilder.from(spec));
  }

  public void testParse_weakKeysCannotHaveValue() {
    try {
      parse("weakKeys=true");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_repeatedKeyStrength() {
    try {
      parse("weakKeys, weakKeys");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_softValues() {
    CacheBuilderSpec spec = parse("softValues");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertEquals(Strength.SOFT, spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().softValues(), CacheBuilder.from(spec));
  }

  public void testParse_softValuesCannotHaveValue() {
    try {
      parse("softValues=true");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_weakValues() {
    CacheBuilderSpec spec = parse("weakValues");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertEquals(Strength.WEAK, spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().weakValues(), CacheBuilder.from(spec));
  }

  public void testParse_weakValuesCannotHaveValue() {
    try {
      parse("weakValues=true");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_repeatedValueStrength() {
    try {
      parse("softValues, softValues");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }

    try {
      parse("softValues, weakValues");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }

    try {
      parse("weakValues, softValues");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }

    try {
      parse("weakValues, weakValues");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_writeExpirationDays() {
    CacheBuilderSpec spec = parse("expireAfterWrite=10d");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(24 * 60 * 60 * 10L, spec.writeExpirationDuration);
    assertNull(spec.accessExpirationTimeUnit);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterWrite(24 * 60 * 60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_writeExpirationHours() {
    CacheBuilderSpec spec = parse("expireAfterWrite=150h");
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(60 * 60 * 150L, spec.writeExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterWrite(60 * 60 * 150L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_writeExpirationMinutes() {
    CacheBuilderSpec spec = parse("expireAfterWrite=10m");
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(60 * 10L, spec.writeExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterWrite(60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_writeExpirationSeconds() {
    CacheBuilderSpec spec = parse("expireAfterWrite=10s");
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(10L, spec.writeExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_writeExpirationRepeated() {
    try {
      parse(
          "expireAfterWrite=10s,expireAfterWrite=10m");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_accessExpirationDays() {
    CacheBuilderSpec spec = parse("expireAfterAccess=10d");
    assertNull(spec.initialCapacity);
    assertNull(spec.maximumSize);
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertNull(spec.keyStrength);
    assertNull(spec.valueStrength);
    assertNull(spec.writeExpirationTimeUnit);
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(24 * 60 * 60 * 10L, spec.accessExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterAccess(24 * 60 * 60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_accessExpirationHours() {
    CacheBuilderSpec spec = parse("expireAfterAccess=150h");
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(60 * 60 * 150L, spec.accessExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterAccess(60 * 60 * 150L, TimeUnit.SECONDS), CacheBuilder.from(spec));
  }

  public void testParse_accessExpirationMinutes() {
    CacheBuilderSpec spec = parse("expireAfterAccess=10m");
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(60 * 10L, spec.accessExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterAccess(60 * 10L, TimeUnit.SECONDS),
        CacheBuilder.from(spec));
  }

  public void testParse_accessExpirationSeconds() {
    CacheBuilderSpec spec = parse("expireAfterAccess=10s");
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(10L, spec.accessExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.SECONDS),
        CacheBuilder.from(spec));
  }

  public void testParse_accessExpirationRepeated() {
    try {
      parse(
          "expireAfterAccess=10s,expireAfterAccess=10m");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_recordStats() {
    CacheBuilderSpec spec = parse("recordStats");
    assertTrue(spec.recordStats);
    assertCacheBuilderEquivalence(CacheBuilder.newBuilder().recordStats(), CacheBuilder.from(spec));
  }

  public void testParse_recordStatsValueSpecified() {
    try {
      parse("recordStats=True");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_recordStatsRepeated() {
    try {
      parse("recordStats,recordStats");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_accessExpirationAndWriteExpiration() {
    CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m");
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(60 * 9L, spec.writeExpirationDuration);
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(10L, spec.accessExpirationDuration);
    assertCacheBuilderEquivalence(
        CacheBuilder.newBuilder()
          .expireAfterAccess(10L, TimeUnit.SECONDS)
          .expireAfterWrite(60 * 9L, TimeUnit.SECONDS),
        CacheBuilder.from(spec));
  }

  public void testParse_multipleKeys() {
    CacheBuilderSpec spec = parse("initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
        + "weakKeys,weakValues,expireAfterAccess=10m,expireAfterWrite=1h");
    assertEquals(10, spec.initialCapacity.intValue());
    assertEquals(20, spec.maximumSize.intValue());
    assertNull(spec.maximumWeight);
    assertEquals(30, spec.concurrencyLevel.intValue());
    assertEquals(Strength.WEAK, spec.keyStrength);
    assertEquals(Strength.WEAK, spec.valueStrength);
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
    assertEquals(60 * 60 * 1L, spec.writeExpirationDuration);
    assertEquals(60 * 10L, spec.accessExpirationDuration);
    CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
        .initialCapacity(10)
        .maximumSize(20)
        .concurrencyLevel(30)
        .weakKeys()
        .weakValues()
        .expireAfterAccess(60 * 10L, TimeUnit.SECONDS)
        .expireAfterWrite(60 * 60 * 1L, TimeUnit.SECONDS);
    assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
  }

  public void testParse_whitespaceAllowed() {
    CacheBuilderSpec spec = parse(" initialCapacity=10,\nmaximumSize=20,\t\r"
        + "weakKeys \t ,softValues \n , \r  expireAfterWrite \t =  15s\n\n");
    assertEquals(10, spec.initialCapacity.intValue());
    assertEquals(20, spec.maximumSize.intValue());
    assertNull(spec.maximumWeight);
    assertNull(spec.concurrencyLevel);
    assertEquals(Strength.WEAK, spec.keyStrength);
    assertEquals(Strength.SOFT, spec.valueStrength);
    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
    assertEquals(15L, spec.writeExpirationDuration);
    assertNull(spec.accessExpirationTimeUnit);
    CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
        .initialCapacity(10)
        .maximumSize(20)
        .weakKeys()
        .softValues()
        .expireAfterWrite(15L, TimeUnit.SECONDS);
    assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
  }

  public void testParse_unknownKey() {
    try {
      parse("foo=17");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testParse_extraCommaIsInvalid() {
    try {
      parse("weakKeys,");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }

    try {
      parse(",weakKeys");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }

    try {
      parse("weakKeys,,softValues");
      fail("Expected exception");
    } catch (IllegalArgumentException expected) {
      // expected
    }
  }

  public void testEqualsAndHashCode() {
    new EqualsTester()
        .addEqualityGroup(parse(""), parse(""))
        .addEqualityGroup(parse("concurrencyLevel=7"), parse("concurrencyLevel=7"))
        .addEqualityGroup(parse("concurrencyLevel=15"), parse("concurrencyLevel=15"))
        .addEqualityGroup(parse("initialCapacity=7"), parse("initialCapacity=7"))
        .addEqualityGroup(parse("initialCapacity=15"), parse("initialCapacity=15"))
        .addEqualityGroup(parse("maximumSize=7"), parse("maximumSize=7"))
        .addEqualityGroup(parse("maximumSize=15"), parse("maximumSize=15"))
        .addEqualityGroup(parse("maximumWeight=7"), parse("maximumWeight=7"))
        .addEqualityGroup(parse("maximumWeight=15"), parse("maximumWeight=15"))
        .addEqualityGroup(parse("expireAfterAccess=60s"), parse("expireAfterAccess=1m"))
        .addEqualityGroup(parse("expireAfterAccess=60m"), parse("expireAfterAccess=1h"))
        .addEqualityGroup(parse("expireAfterWrite=60s"), parse("expireAfterWrite=1m"))
        .addEqualityGroup(parse("expireAfterWrite=60m"), parse("expireAfterWrite=1h"))
        .addEqualityGroup(parse("weakKeys"), parse("weakKeys"))
        .addEqualityGroup(parse("softValues"), parse("softValues"))
        .addEqualityGroup(parse("weakValues"), parse("weakValues"))
        .addEqualityGroup(parse("recordStats"), parse("recordStats"))
        .testEquals();
  }

  public void testMaximumWeight_withWeigher() {
    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
    builder
        .weigher(constantWeigher(42))
        .build(CacheLoader.from(Suppliers.ofInstance(null)));
  }

  public void testMaximumWeight_withoutWeigher() {
    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
    try {
      builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
      fail();
    } catch (IllegalStateException expected) {}
  }

  public void testMaximumSize_withWeigher() {
    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
    builder
        .weigher(constantWeigher(42))
        .build(CacheLoader.from(Suppliers.ofInstance(null)));
  }

  public void testMaximumSize_withoutWeigher() {
    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
    builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
  }

  public void testDisableCaching() {
    // Functional test: assert that CacheBuilderSpec.disableCaching()
    // disables caching.  It's irrelevant how it does so.
    CacheBuilder<Object, Object> builder = CacheBuilder.from(CacheBuilderSpec.disableCaching());
    Object key = new Object();
    Object value = new Object();
    LoadingCache<Object, Object> cache = builder.build(
        CacheLoader.from(Suppliers.ofInstance(value)));
    assertSame(value, cache.getUnchecked(key));
    assertEquals(0, cache.size());
    assertFalse(cache.asMap().containsKey(key));
  }

  public void testCacheBuilderFrom_string() {
    CacheBuilder<?, ?> fromString = CacheBuilder.from(
        "initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
        + "weakKeys,weakValues,expireAfterAccess=10m");
    CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
        .initialCapacity(10)
        .maximumSize(20)
        .concurrencyLevel(30)
        .weakKeys()
        .weakValues()
        .expireAfterAccess(60 * 10L, TimeUnit.SECONDS);
    assertCacheBuilderEquivalence(expected, fromString);
  }

  private static void assertCacheBuilderEquivalence(CacheBuilder<?, ?> a, CacheBuilder<?, ?> b) {
    assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel);
    assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos);
    assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos);
    assertEquals("initialCapacity", a.initialCapacity, b.initialCapacity);
    assertEquals("maximumSize", a.maximumSize, b.maximumSize);
    assertEquals("maximumWeight", a.maximumWeight, b.maximumWeight);
    assertEquals("refreshNanos", a.refreshNanos, b.refreshNanos);
    assertEquals("keyEquivalence", a.keyEquivalence, b.keyEquivalence);
    assertEquals("keyStrength", a.keyStrength, b.keyStrength);
    assertEquals("removalListener", a.removalListener, b.removalListener);
    assertEquals("weigher", a.weigher, b.weigher);
    assertEquals("valueEquivalence", a.valueEquivalence, b.valueEquivalence);
    assertEquals("valueStrength", a.valueStrength, b.valueStrength);
    assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier);
    assertEquals("ticker", a.ticker, b.ticker);
    assertEquals("recordStats", a.isRecordingStats(), b.isRecordingStats());
  }
}
