/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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.
 */

#include <stdlib.h>
#include <utils/JenkinsHash.h>
#include <utils/LruCache.h>
#include <cutils/log.h>
#include <gtest/gtest.h>

namespace android {

typedef int SimpleKey;
typedef const char* StringValue;

struct ComplexKey {
    int k;

    explicit ComplexKey(int k) : k(k) {
        instanceCount += 1;
    }

    ComplexKey(const ComplexKey& other) : k(other.k) {
        instanceCount += 1;
    }

    ~ComplexKey() {
        instanceCount -= 1;
    }

    bool operator ==(const ComplexKey& other) const {
        return k == other.k;
    }

    bool operator !=(const ComplexKey& other) const {
        return k != other.k;
    }

    static ssize_t instanceCount;
};

ssize_t ComplexKey::instanceCount = 0;

template<> inline hash_t hash_type(const ComplexKey& value) {
    return hash_type(value.k);
}

struct ComplexValue {
    int v;

    explicit ComplexValue(int v) : v(v) {
        instanceCount += 1;
    }

    ComplexValue(const ComplexValue& other) : v(other.v) {
        instanceCount += 1;
    }

    ~ComplexValue() {
        instanceCount -= 1;
    }

    static ssize_t instanceCount;
};

ssize_t ComplexValue::instanceCount = 0;

typedef LruCache<ComplexKey, ComplexValue> ComplexCache;

class EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> {
public:
    EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { }
    ~EntryRemovedCallback() {}
    void operator()(SimpleKey& k, StringValue& v) {
        callbackCount += 1;
        lastKey = k;
        lastValue = v;
    }
    ssize_t callbackCount;
    SimpleKey lastKey;
    StringValue lastValue;
};

class LruCacheTest : public testing::Test {
protected:
    virtual void SetUp() {
        ComplexKey::instanceCount = 0;
        ComplexValue::instanceCount = 0;
    }

    virtual void TearDown() {
        ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
    }

    void assertInstanceCount(ssize_t keys, ssize_t values) {
        if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) {
            FAIL() << "Expected " << keys << " keys and " << values << " values "
                    "but there were actually " << ComplexKey::instanceCount << " keys and "
                    << ComplexValue::instanceCount << " values";
        }
    }
};

TEST_F(LruCacheTest, Empty) {
    LruCache<SimpleKey, StringValue> cache(100);

    EXPECT_EQ(NULL, cache.get(0));
    EXPECT_EQ(0u, cache.size());
}

TEST_F(LruCacheTest, Simple) {
    LruCache<SimpleKey, StringValue> cache(100);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    EXPECT_STREQ("one", cache.get(1));
    EXPECT_STREQ("two", cache.get(2));
    EXPECT_STREQ("three", cache.get(3));
    EXPECT_EQ(3u, cache.size());
}

TEST_F(LruCacheTest, MaxCapacity) {
    LruCache<SimpleKey, StringValue> cache(2);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    EXPECT_EQ(NULL, cache.get(1));
    EXPECT_STREQ("two", cache.get(2));
    EXPECT_STREQ("three", cache.get(3));
    EXPECT_EQ(2u, cache.size());
}

TEST_F(LruCacheTest, RemoveLru) {
    LruCache<SimpleKey, StringValue> cache(100);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    cache.removeOldest();
    EXPECT_EQ(NULL, cache.get(1));
    EXPECT_STREQ("two", cache.get(2));
    EXPECT_STREQ("three", cache.get(3));
    EXPECT_EQ(2u, cache.size());
}

TEST_F(LruCacheTest, GetUpdatesLru) {
    LruCache<SimpleKey, StringValue> cache(100);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    EXPECT_STREQ("one", cache.get(1));
    cache.removeOldest();
    EXPECT_STREQ("one", cache.get(1));
    EXPECT_EQ(NULL, cache.get(2));
    EXPECT_STREQ("three", cache.get(3));
    EXPECT_EQ(2u, cache.size());
}

uint32_t hash_int(int x) {
    return JenkinsHashWhiten(JenkinsHashMix(0, x));
}

TEST_F(LruCacheTest, StressTest) {
    const size_t kCacheSize = 512;
    LruCache<SimpleKey, StringValue> cache(512);
    const size_t kNumKeys = 16 * 1024;
    const size_t kNumIters = 100000;
    char* strings[kNumKeys];

    for (size_t i = 0; i < kNumKeys; i++) {
        strings[i] = (char *)malloc(16);
        sprintf(strings[i], "%zu", i);
    }

    srandom(12345);
    int hitCount = 0;
    for (size_t i = 0; i < kNumIters; i++) {
        int index = random() % kNumKeys;
        uint32_t key = hash_int(index);
        const char *val = cache.get(key);
        if (val != NULL) {
            EXPECT_EQ(strings[index], val);
            hitCount++;
        } else {
            cache.put(key, strings[index]);
        }
    }
    size_t expectedHitCount = kNumIters * kCacheSize / kNumKeys;
    EXPECT_LT(int(expectedHitCount * 0.9), hitCount);
    EXPECT_GT(int(expectedHitCount * 1.1), hitCount);
    EXPECT_EQ(kCacheSize, cache.size());

    for (size_t i = 0; i < kNumKeys; i++) {
        free((void *)strings[i]);
    }
}

TEST_F(LruCacheTest, NoLeak) {
    ComplexCache cache(100);

    cache.put(ComplexKey(0), ComplexValue(0));
    cache.put(ComplexKey(1), ComplexValue(1));
    EXPECT_EQ(2, cache.size());
    assertInstanceCount(2, 3);  // the null value counts as an instance
}

TEST_F(LruCacheTest, Clear) {
    ComplexCache cache(100);

    cache.put(ComplexKey(0), ComplexValue(0));
    cache.put(ComplexKey(1), ComplexValue(1));
    EXPECT_EQ(2, cache.size());
    assertInstanceCount(2, 3);
    cache.clear();
    assertInstanceCount(0, 1);
}

TEST_F(LruCacheTest, ClearNoDoubleFree) {
    {
        ComplexCache cache(100);

        cache.put(ComplexKey(0), ComplexValue(0));
        cache.put(ComplexKey(1), ComplexValue(1));
        EXPECT_EQ(2, cache.size());
        assertInstanceCount(2, 3);
        cache.removeOldest();
        cache.clear();
        assertInstanceCount(0, 1);
    }
    assertInstanceCount(0, 0);
}

TEST_F(LruCacheTest, ClearReuseOk) {
    ComplexCache cache(100);

    cache.put(ComplexKey(0), ComplexValue(0));
    cache.put(ComplexKey(1), ComplexValue(1));
    EXPECT_EQ(2, cache.size());
    assertInstanceCount(2, 3);
    cache.clear();
    assertInstanceCount(0, 1);
    cache.put(ComplexKey(0), ComplexValue(0));
    cache.put(ComplexKey(1), ComplexValue(1));
    EXPECT_EQ(2, cache.size());
    assertInstanceCount(2, 3);
}

TEST_F(LruCacheTest, Callback) {
    LruCache<SimpleKey, StringValue> cache(100);
    EntryRemovedCallback callback;
    cache.setOnEntryRemovedListener(&callback);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    EXPECT_EQ(3, cache.size());
    cache.removeOldest();
    EXPECT_EQ(1, callback.callbackCount);
    EXPECT_EQ(1, callback.lastKey);
    EXPECT_STREQ("one", callback.lastValue);
}

TEST_F(LruCacheTest, CallbackOnClear) {
    LruCache<SimpleKey, StringValue> cache(100);
    EntryRemovedCallback callback;
    cache.setOnEntryRemovedListener(&callback);

    cache.put(1, "one");
    cache.put(2, "two");
    cache.put(3, "three");
    EXPECT_EQ(3, cache.size());
    cache.clear();
    EXPECT_EQ(3, callback.callbackCount);
}

}
