/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkRefCnt.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkMalloc.h"
#include "src/core/SkCachedData.h"
#include "src/lazy/SkDiscardableMemoryPool.h"
#include "tests/Test.h"

#include <cstring>

class SkDiscardableMemory;

enum LockedState {
    kUnlocked,
    kLocked,
};

enum CachedState {
    kNotInCache,
    kInCache,
};

static void check_data(skiatest::Reporter* reporter, SkCachedData* data,
                       int refcnt, CachedState cacheState, LockedState lockedState) {
    REPORTER_ASSERT(reporter, data->testing_only_getRefCnt() == refcnt);
    REPORTER_ASSERT(reporter, data->testing_only_isInCache() == (kInCache == cacheState));
    REPORTER_ASSERT(reporter, data->testing_only_isLocked() == (lockedState == kLocked));
}

static SkCachedData* make_data(size_t size, SkDiscardableMemoryPool* pool) {
    if (pool) {
        SkDiscardableMemory* dm = pool->create(size);
        // the pool "can" return null, but it shouldn't in these controlled conditions
        SkASSERT_RELEASE(dm);
        return new SkCachedData(size, dm);
    } else {
        return new SkCachedData(sk_malloc_throw(size), size);
    }
}

// returns with the data locked by client and cache
static SkCachedData* test_locking(skiatest::Reporter* reporter,
                                  size_t size, SkDiscardableMemoryPool* pool) {
    SkCachedData* data = make_data(size, pool);

    memset(data->writable_data(), 0x80, size);  // just to use writable_data()

    check_data(reporter, data, 1, kNotInCache, kLocked);

    data->ref();
    check_data(reporter, data, 2, kNotInCache, kLocked);
    data->unref();
    check_data(reporter, data, 1, kNotInCache, kLocked);

    data->attachToCacheAndRef();
    check_data(reporter, data, 2, kInCache, kLocked);

    data->unref();
    check_data(reporter, data, 1, kInCache, kUnlocked);

    data->ref();
    check_data(reporter, data, 2, kInCache, kLocked);

    return data;
}

/*
 *  SkCachedData behaves differently (regarding its locked/unlocked state) depending on
 *  when it is in the cache or not. Being in the cache is signaled by calling attachToCacheAndRef()
 *  instead of ref(). (and balanced by detachFromCacheAndUnref).
 *
 *  Thus, among other things, we test the end-of-life behavior when the client is the last owner
 *  and when the cache is.
 */
DEF_TEST(CachedData, reporter) {
    sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(1000));

    for (int useDiscardable = 0; useDiscardable <= 1; ++useDiscardable) {
        const size_t size = 100;

        // test with client as last owner
        SkCachedData* data = test_locking(reporter, size, useDiscardable ? pool.get() : nullptr);
        check_data(reporter, data, 2, kInCache, kLocked);
        data->detachFromCacheAndUnref();
        check_data(reporter, data, 1, kNotInCache, kLocked);
        data->unref();

        // test with cache as last owner
        data = test_locking(reporter, size, useDiscardable ? pool.get() : nullptr);
        check_data(reporter, data, 2, kInCache, kLocked);
        data->unref();
        check_data(reporter, data, 1, kInCache, kUnlocked);
        data->detachFromCacheAndUnref();
    }
}
