/*
*******************************************************************************
* Copyright (C) 2015, International Business Machines Corporation and         *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File UNIFIEDCACHETEST.CPP
*
********************************************************************************
*/
#include "cstring.h"
#include "intltest.h"
#include "unifiedcache.h"
#include "unicode/datefmt.h"

class UCTItem : public SharedObject {
  public:
    char *value;
    UCTItem(const char *x) : value(NULL) { 
        value = uprv_strdup(x);
    }
    virtual ~UCTItem() {
        uprv_free(value);
    }
};

class UCTItem2 : public SharedObject {
};

U_NAMESPACE_BEGIN

template<> U_EXPORT
const UCTItem *LocaleCacheKey<UCTItem>::createObject(
        const void *context, UErrorCode &status) const {
    const UnifiedCache *cacheContext = (const UnifiedCache *) context;
    if (uprv_strcmp(fLoc.getName(), "zh") == 0) {
        status = U_MISSING_RESOURCE_ERROR;
        return NULL;
    }
    if (uprv_strcmp(fLoc.getLanguage(), fLoc.getName()) != 0) {
        const UCTItem *item = NULL;
        if (cacheContext == NULL) {
            UnifiedCache::getByLocale(fLoc.getLanguage(), item, status);
        } else {
            cacheContext->get(LocaleCacheKey<UCTItem>(fLoc.getLanguage()), item, status);
        }
        if (U_FAILURE(status)) {
            return NULL;
        }
        return item;
    }
    UCTItem *result = new UCTItem(fLoc.getName());
    result->addRef();
    return result;
}

template<> U_EXPORT
const UCTItem2 *LocaleCacheKey<UCTItem2>::createObject(
        const void * /*unused*/, UErrorCode & /*status*/) const {
    return NULL;
}

U_NAMESPACE_END


class UnifiedCacheTest : public IntlTest {
public:
    UnifiedCacheTest() {
    }
    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
private:
    void TestEvictionPolicy();
    void TestBounded();
    void TestBasic();
    void TestError();
    void TestHashEquals();
    void TestEvictionUnderStress();
};

void UnifiedCacheTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) {
  TESTCASE_AUTO_BEGIN;
  TESTCASE_AUTO(TestEvictionPolicy);
  TESTCASE_AUTO(TestBounded);
  TESTCASE_AUTO(TestBasic);
  TESTCASE_AUTO(TestError);
  TESTCASE_AUTO(TestHashEquals);
  TESTCASE_AUTO(TestEvictionUnderStress);
  TESTCASE_AUTO_END;
}

void UnifiedCacheTest::TestEvictionUnderStress() {
    int32_t localeCount;
    const Locale *locales = DateFormat::getAvailableLocales(localeCount);
    UErrorCode status = U_ZERO_ERROR;
    const UnifiedCache *cache = UnifiedCache::getInstance(status);
    int64_t evictedCountBefore = cache->autoEvictedCount();
    for (int32_t i = 0; i < localeCount; ++i) {
        LocalPointer<DateFormat> ptr(DateFormat::createInstanceForSkeleton("yMd", locales[i], status));
    }
    int64_t evictedCountAfter = cache->autoEvictedCount();
    if (evictedCountBefore == evictedCountAfter) {
        errln("%s:%d Items should have been evicted from cache",
               __FILE__, __LINE__);
    }
}

void UnifiedCacheTest::TestEvictionPolicy() {
    UErrorCode status = U_ZERO_ERROR;

    // We have to call this first or else calling the UnifiedCache
    // ctor will fail. This is by design to deter clients from using the 
    // cache API incorrectly by creating their own cache instances.
    UnifiedCache::getInstance(status);

    // We create our own local UnifiedCache instance to ensure we have
    // complete control over it. Real clients should never ever create
    // their own cache!
    UnifiedCache cache(status);
    assertSuccess("", status);

    // Don't allow unused entries to exeed more than 100% of in use entries.
    cache.setEvictionPolicy(0, 100, status);

    static const char *locales[] = {
            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
            "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"};

    const UCTItem *usedReferences[] = {NULL, NULL, NULL, NULL, NULL};
    const UCTItem *unusedReference = NULL;

    // Add 5 in-use entries
    for (int32_t i = 0; i < UPRV_LENGTHOF(usedReferences); i++) {
        cache.get(
                LocaleCacheKey<UCTItem>(locales[i]),
                &cache,
                usedReferences[i],
                status);
    }

    // Add 10 not in use entries.
    for (int32_t i = 0; i < 10; ++i) {
        cache.get(
                LocaleCacheKey<UCTItem>(
                        locales[i + UPRV_LENGTHOF(usedReferences)]),
                &cache,
                unusedReference,
                status);
    }
    unusedReference->removeRef();

    // unused count not to exeed in use count
    assertEquals("", UPRV_LENGTHOF(usedReferences), cache.unusedCount());
    assertEquals("", 2*UPRV_LENGTHOF(usedReferences), cache.keyCount());

    // Free up those used entries.
    for (int32_t i = 0; i < UPRV_LENGTHOF(usedReferences); i++) {
        usedReferences[i]->removeRef();
    }

    // This should free up all cache items
    assertEquals("", 0, cache.keyCount());

    assertSuccess("", status);
}



void UnifiedCacheTest::TestBounded() {
    UErrorCode status = U_ZERO_ERROR;

    // We have to call this first or else calling the UnifiedCache
    // ctor will fail. This is by design to deter clients from using the
    // cache API incorrectly by creating their own cache instances.
    UnifiedCache::getInstance(status);

    // We create our own local UnifiedCache instance to ensure we have
    // complete control over it. Real clients should never ever create
    // their own cache!
    UnifiedCache cache(status);
    assertSuccess("", status);

    // Maximum unused count is 3.
    cache.setEvictionPolicy(3, 0, status);

    // Our cache will hold up to 3 unused key-value pairs
    // We test the following invariants:
    // 1. unusedCount <= 3
    // 2. cache->get(X) always returns the same reference as long as caller
    //   already holds references to that same object. 

    // We first add 5 key-value pairs with two distinct values, "en" and "fr"
    // keeping all those references.

    const UCTItem *en = NULL;
    const UCTItem *enGb = NULL;
    const UCTItem *enUs = NULL;
    const UCTItem *fr = NULL;
    const UCTItem *frFr = NULL;
    cache.get(LocaleCacheKey<UCTItem>("en_US"), &cache, enUs, status);
    cache.get(LocaleCacheKey<UCTItem>("en"), &cache, en, status);
    assertEquals("", 1, cache.unusedCount());
    cache.get(LocaleCacheKey<UCTItem>("en_GB"), &cache, enGb, status);
    cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, frFr, status);
    cache.get(LocaleCacheKey<UCTItem>("fr"), &cache, fr, status);

    // Client holds two unique references, "en" and "fr" the other three
    // entries are eligible for eviction. 
    assertEquals("", 3, cache.unusedCount());
    assertEquals("", 5, cache.keyCount());

    // Exercise cache more but don't hold the references except for
    // the last one. At the end of this, we will hold references to one
    // additional distinct value, so we will have references to 3 distinct
    // values.
    const UCTItem *throwAway = NULL;
    cache.get(LocaleCacheKey<UCTItem>("zn_AA"), &cache, throwAway, status);
    cache.get(LocaleCacheKey<UCTItem>("sr_AA"), &cache, throwAway, status);
    cache.get(LocaleCacheKey<UCTItem>("de_AU"), &cache, throwAway, status);

    const UCTItem *deAu(throwAway);
    deAu->addRef();

    // Client holds three unique references, "en", "fr", "de" although we
    // could have a total of 8 entries in the cache maxUnusedCount == 3
    // so we have only 6 entries.
    assertEquals("", 3, cache.unusedCount());
    assertEquals("", 6, cache.keyCount());

    // For all the references we have, cache must continue to return
    // those same references (#2)

    cache.get(LocaleCacheKey<UCTItem>("en"), &cache, throwAway, status);
    if (throwAway != en) {
        errln("Expected en to resolve to the same object.");
    }
    cache.get(LocaleCacheKey<UCTItem>("en_US"), &cache, throwAway, status);
    if (throwAway != enUs) {
        errln("Expected enUs to resolve to the same object.");
    }
    cache.get(LocaleCacheKey<UCTItem>("en_GB"), &cache, throwAway, status);
    if (throwAway != enGb) {
        errln("Expected enGb to resolve to the same object.");
    }
    cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, throwAway, status);
    if (throwAway != frFr) {
        errln("Expected frFr to resolve to the same object.");
    }
    cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, throwAway, status);
    cache.get(LocaleCacheKey<UCTItem>("fr"), &cache, throwAway, status);
    if (throwAway != fr) {
        errln("Expected fr to resolve to the same object.");
    }
    cache.get(LocaleCacheKey<UCTItem>("de_AU"), &cache, throwAway, status);
    if (throwAway != deAu) {
        errln("Expected deAu to resolve to the same object.");
    }

    assertEquals("", 3, cache.unusedCount());
    assertEquals("", 6, cache.keyCount());

    // Now we hold a references to two more distinct values. Cache size 
    // should grow to 8.
    const UCTItem *es = NULL;
    const UCTItem *ru = NULL;
    cache.get(LocaleCacheKey<UCTItem>("es"), &cache, es, status);
    cache.get(LocaleCacheKey<UCTItem>("ru"), &cache, ru, status);
    assertEquals("", 3, cache.unusedCount());
    assertEquals("", 8, cache.keyCount());

    // Now release all the references we hold except for
    // es, ru, and en
    SharedObject::clearPtr(enGb);
    SharedObject::clearPtr(enUs);
    SharedObject::clearPtr(fr);
    SharedObject::clearPtr(frFr);
    SharedObject::clearPtr(deAu);
    SharedObject::clearPtr(es);
    SharedObject::clearPtr(ru);
    SharedObject::clearPtr(en);
    SharedObject::clearPtr(throwAway);

    // Size of cache should magically drop to 3.
    assertEquals("", 3, cache.unusedCount());
    assertEquals("", 3, cache.keyCount());

    // Be sure nothing happens setting the eviction policy in the middle of
    // a run.
    cache.setEvictionPolicy(3, 0, status);
    assertSuccess("", status);
    
}

void UnifiedCacheTest::TestBasic() {
    UErrorCode status = U_ZERO_ERROR;
    const UnifiedCache *cache = UnifiedCache::getInstance(status);
    assertSuccess("", status);
    cache->flush();
    int32_t baseCount = cache->keyCount();
    const UCTItem *en = NULL;
    const UCTItem *enGb = NULL;
    const UCTItem *enGb2 = NULL;
    const UCTItem *enUs = NULL;
    const UCTItem *fr = NULL;
    const UCTItem *frFr = NULL;
    cache->get(LocaleCacheKey<UCTItem>("en"), en, status);
    cache->get(LocaleCacheKey<UCTItem>("en_US"), enUs, status);
    cache->get(LocaleCacheKey<UCTItem>("en_GB"), enGb, status);
    cache->get(LocaleCacheKey<UCTItem>("fr_FR"), frFr, status);
    cache->get(LocaleCacheKey<UCTItem>("fr"), fr, status);
    cache->get(LocaleCacheKey<UCTItem>("en_GB"), enGb2, status);
    SharedObject::clearPtr(enGb2);
    if (enGb != enUs) {
        errln("Expected en_GB and en_US to resolve to same object.");
    } 
    if (fr != frFr) {
        errln("Expected fr and fr_FR to resolve to same object.");
    } 
    if (enGb == fr) {
        errln("Expected en_GB and fr to return different objects.");
    }
    assertSuccess("", status);
    // en_US, en_GB, en share one object; fr_FR and fr don't share.
    // 5 keys in all.
    assertEquals("", baseCount + 5, cache->keyCount());
    SharedObject::clearPtr(enGb);
    cache->flush();

    // Only 2 unique values in the cache. flushing trims cache down
    // to this minimum size.
    assertEquals("", baseCount + 2, cache->keyCount());
    SharedObject::clearPtr(enUs);
    SharedObject::clearPtr(en);
    cache->flush();
    // With en_GB and en_US and en cleared there are no more hard references to
    // the "en" object, so it gets flushed and the keys that refer to it
    // get removed from the cache. Now we have just one unique value, fr, in
    // the cache
    assertEquals("", baseCount + 1, cache->keyCount());
    SharedObject::clearPtr(fr);
    cache->flush();
    assertEquals("", baseCount + 1, cache->keyCount());
    SharedObject::clearPtr(frFr);
    cache->flush();
    assertEquals("", baseCount + 0, cache->keyCount());
    assertSuccess("", status);
}

void UnifiedCacheTest::TestError() {
    UErrorCode status = U_ZERO_ERROR;
    const UnifiedCache *cache = UnifiedCache::getInstance(status);
    assertSuccess("", status);
    cache->flush();
    int32_t baseCount = cache->keyCount();
    const UCTItem *zh = NULL;
    const UCTItem *zhTw = NULL;
    const UCTItem *zhHk = NULL;

    status = U_ZERO_ERROR;
    cache->get(LocaleCacheKey<UCTItem>("zh"), zh, status);
    if (status != U_MISSING_RESOURCE_ERROR) {
        errln("Expected U_MISSING_RESOURCE_ERROR");
    }
    status = U_ZERO_ERROR;
    cache->get(LocaleCacheKey<UCTItem>("zh_TW"), zhTw, status);
    if (status != U_MISSING_RESOURCE_ERROR) {
        errln("Expected U_MISSING_RESOURCE_ERROR");
    }
    status = U_ZERO_ERROR;
    cache->get(LocaleCacheKey<UCTItem>("zh_HK"), zhHk, status);
    if (status != U_MISSING_RESOURCE_ERROR) {
        errln("Expected U_MISSING_RESOURCE_ERROR");
    }
    // 3 keys in cache zh, zhTW, zhHk all pointing to error placeholders
    assertEquals("", baseCount + 3, cache->keyCount());
    cache->flush();
    // error placeholders have no hard references so they always get flushed. 
    assertEquals("", baseCount + 0, cache->keyCount());
}

void UnifiedCacheTest::TestHashEquals() {
    LocaleCacheKey<UCTItem> key1("en_US");
    LocaleCacheKey<UCTItem> key2("en_US");
    LocaleCacheKey<UCTItem> diffKey1("en_UT");
    LocaleCacheKey<UCTItem2> diffKey2("en_US");
    assertTrue("", key1.hashCode() == key2.hashCode());
    assertTrue("", key1.hashCode() != diffKey1.hashCode());
    assertTrue("", key1.hashCode() != diffKey2.hashCode());
    assertTrue("", diffKey1.hashCode() != diffKey2.hashCode());
    assertTrue("", key1 == key2);
    assertTrue("", key1 != diffKey1);
    assertTrue("", key1 != diffKey2);
    assertTrue("", diffKey1 != diffKey2);
}

extern IntlTest *createUnifiedCacheTest() {
    return new UnifiedCacheTest();
}
