// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* 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() {
#if !UCONFIG_NO_FORMATTING
    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) {
        dataerrln("%s:%d Items should have been evicted from cache",
               __FILE__, __LINE__);
    }
#endif /* #if !UCONFIG_NO_FORMATTING */
}

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();
}
