/*
 * 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/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSurface.h"
#include "src/core/SkBitmapCache.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkResourceCache.h"
#include "src/image/SkImage_Base.h"
#include "src/lazy/SkDiscardableMemoryPool.h"
#include "tests/Test.h"

////////////////////////////////////////////////////////////////////////////////////////

enum LockedState {
    kNotLocked,
    kLocked,
};

enum CachedState {
    kNotInCache,
    kInCache,
};

static void check_data(skiatest::Reporter* reporter, const 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));
    bool isLocked = (data->data() != nullptr);
    REPORTER_ASSERT(reporter, isLocked == (lockedState == kLocked));
}

static void test_mipmapcache(skiatest::Reporter* reporter, SkResourceCache* cache) {
    cache->purgeAll();

    SkBitmap src;
    src.allocN32Pixels(5, 5);
    src.setImmutable();
    sk_sp<SkImage> img = src.asImage();
    const auto desc = SkBitmapCacheDesc::Make(img.get());

    const SkMipmap* mipmap = SkMipmapCache::FindAndRef(desc, cache);
    REPORTER_ASSERT(reporter, nullptr == mipmap);

    mipmap = SkMipmapCache::AddAndRef(as_IB(img.get()), cache);
    REPORTER_ASSERT(reporter, mipmap);

    {
        const SkMipmap* mm = SkMipmapCache::FindAndRef(desc, cache);
        REPORTER_ASSERT(reporter, mm);
        REPORTER_ASSERT(reporter, mm == mipmap);
        mm->unref();
    }

    check_data(reporter, mipmap, 2, kInCache, kLocked);

    mipmap->unref();
    // tricky, since technically after this I'm no longer an owner, but since the cache is
    // local, I know it won't get purged behind my back
    check_data(reporter, mipmap, 1, kInCache, kNotLocked);

    // find us again
    mipmap = SkMipmapCache::FindAndRef(desc, cache);
    check_data(reporter, mipmap, 2, kInCache, kLocked);

    cache->purgeAll();
    check_data(reporter, mipmap, 1, kNotInCache, kLocked);

    mipmap->unref();
}

static void test_mipmap_notify(skiatest::Reporter* reporter, SkResourceCache* cache) {
    const int N = 3;

    SkBitmap src[N];
    sk_sp<SkImage> img[N];
    SkBitmapCacheDesc desc[N];
    for (int i = 0; i < N; ++i) {
        src[i].allocN32Pixels(5, 5);
        src[i].setImmutable();
        img[i] = src[i].asImage();
        SkMipmapCache::AddAndRef(as_IB(img[i].get()), cache)->unref();
        desc[i] = SkBitmapCacheDesc::Make(img[i].get());
    }

    for (int i = 0; i < N; ++i) {
        const SkMipmap* mipmap = SkMipmapCache::FindAndRef(desc[i], cache);
        // We're always using a local cache, so we know we won't be purged by other threads
        REPORTER_ASSERT(reporter, mipmap);
        SkSafeUnref(mipmap);

        img[i].reset(); // delete the image, which *should not* remove us from the cache
        mipmap = SkMipmapCache::FindAndRef(desc[i], cache);
        REPORTER_ASSERT(reporter, mipmap);
        SkSafeUnref(mipmap);

        src[i].reset(); // delete the underlying pixelref, which *should* remove us from the cache
        mipmap = SkMipmapCache::FindAndRef(desc[i], cache);
        REPORTER_ASSERT(reporter, !mipmap);
    }
}

#include "src/lazy/SkDiscardableMemoryPool.h"

static SkDiscardableMemoryPool* gPool = nullptr;
static int gFactoryCalls = 0;

static SkDiscardableMemory* pool_factory(size_t bytes) {
    SkASSERT(gPool);
    gFactoryCalls++;
    return gPool->create(bytes);
}

static void testBitmapCache_discarded_bitmap(skiatest::Reporter* reporter, SkResourceCache* cache,
                                             SkResourceCache::DiscardableFactory factory) {
    test_mipmapcache(reporter, cache);
    test_mipmap_notify(reporter, cache);
}

DEF_TEST(BitmapCache_discarded_bitmap, reporter) {
    const size_t byteLimit = 100 * 1024;
    {
        SkResourceCache cache(byteLimit);
        testBitmapCache_discarded_bitmap(reporter, &cache, nullptr);
    }
    {
        sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(byteLimit));
        gPool = pool.get();
        SkResourceCache::DiscardableFactory factory = pool_factory;
        SkResourceCache cache(factory);
        testBitmapCache_discarded_bitmap(reporter, &cache, factory);
    }
    REPORTER_ASSERT(reporter, gFactoryCalls > 0);
}

static void test_discarded_image(skiatest::Reporter* reporter, const SkMatrix& transform,
                                 sk_sp<SkImage> (*buildImage)()) {
    auto surface(SkSurface::MakeRasterN32Premul(10, 10));
    SkCanvas* canvas = surface->getCanvas();

    // SkBitmapCache is global, so other threads could be evicting our bitmaps.  Loop a few times
    // to mitigate this risk.
    const unsigned kRepeatCount = 42;
    for (unsigned i = 0; i < kRepeatCount; ++i) {
        SkAutoCanvasRestore acr(canvas, true);

        sk_sp<SkImage> image(buildImage());

        // draw the image (with a transform, to tickle different code paths) to ensure
        // any associated resources get cached
        canvas->concat(transform);
        // always use high quality to ensure caching when scaled
        canvas->drawImage(image, 0, 0, SkSamplingOptions({1.0f/3, 1.0f/3}));

        const auto desc = SkBitmapCacheDesc::Make(image.get());

        // delete the image
        image.reset(nullptr);

        // all resources should have been purged
        SkBitmap result;
        REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &result));
    }
}


// Verify that associated bitmap cache entries are purged on SkImage destruction.
DEF_TEST(BitmapCache_discarded_image, reporter) {
    // Cache entries associated with SkImages fall into two categories:
    //
    // 1) generated image bitmaps (managed by the image cacherator)
    // 2) scaled/resampled bitmaps (cached when HQ filters are used)
    //
    // To exercise the first cache type, we use generated/picture-backed SkImages.
    // To exercise the latter, we draw scaled bitmap images using HQ filters.

    const SkMatrix xforms[] = {
        SkMatrix::Scale(1, 1),
        SkMatrix::Scale(1.7f, 0.5f),
    };

    for (size_t i = 0; i < std::size(xforms); ++i) {
        test_discarded_image(reporter, xforms[i], []() {
            auto surface(SkSurface::MakeRasterN32Premul(10, 10));
            surface->getCanvas()->clear(SK_ColorCYAN);
            return surface->makeImageSnapshot();
        });

        test_discarded_image(reporter, xforms[i], []() {
            SkPictureRecorder recorder;
            SkCanvas* canvas = recorder.beginRecording(10, 10);
            canvas->clear(SK_ColorCYAN);
            return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(),
                                            SkISize::Make(10, 10), nullptr, nullptr,
                                            SkImage::BitDepth::kU8,
                                            SkColorSpace::MakeSRGB());
        });
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static void* gTestNamespace;

struct TestKey : SkResourceCache::Key {
    int32_t fData;

    TestKey(int sharedID, int32_t data) : fData(data) {
        this->init(&gTestNamespace, sharedID, sizeof(fData));
    }
};

struct TestRec : SkResourceCache::Rec {
    enum {
        kDidInstall = 1 << 0,
    };

    TestKey fKey;
    int*    fFlags;
    bool    fCanBePurged;

    TestRec(int sharedID, int32_t data, int* flagPtr) : fKey(sharedID, data), fFlags(flagPtr) {
        fCanBePurged = false;
    }

    const Key& getKey() const override { return fKey; }
    size_t bytesUsed() const override { return 1024; /* just need a value */ }
    bool canBePurged() override { return fCanBePurged; }
    void postAddInstall(void*) override {
        *fFlags |= kDidInstall;
    }
    const char* getCategory() const override { return "test-category"; }
};

static void test_duplicate_add(SkResourceCache* cache, skiatest::Reporter* reporter,
                               bool purgable) {
    int sharedID = 1;
    int data = 0;

    int flags0 = 0, flags1 = 0;

    auto rec0 = std::make_unique<TestRec>(sharedID, data, &flags0);
    auto rec1 = std::make_unique<TestRec>(sharedID, data, &flags1);
    SkASSERT(rec0->getKey() == rec1->getKey());

    TestRec* r0 = rec0.get();   // save the bare-pointer since we will release rec0
    r0->fCanBePurged = purgable;

    REPORTER_ASSERT(reporter, !(flags0 & TestRec::kDidInstall));
    REPORTER_ASSERT(reporter, !(flags1 & TestRec::kDidInstall));

    cache->add(rec0.release(), nullptr);
    REPORTER_ASSERT(reporter, flags0 & TestRec::kDidInstall);
    REPORTER_ASSERT(reporter, !(flags1 & TestRec::kDidInstall));
    flags0 = 0; // reset the flag

    cache->add(rec1.release(), nullptr);
    if (purgable) {
        // we purged rec0, and did install rec1
        REPORTER_ASSERT(reporter, !(flags0 & TestRec::kDidInstall));
        REPORTER_ASSERT(reporter, flags1 & TestRec::kDidInstall);
    } else {
        // we re-used rec0 and did not install rec1
        REPORTER_ASSERT(reporter, flags0 & TestRec::kDidInstall);
        REPORTER_ASSERT(reporter, !(flags1 & TestRec::kDidInstall));
        r0->fCanBePurged = true;  // so we can cleanup the cache
    }
}

/*
 *  Test behavior when the same key is added more than once.
 */
DEF_TEST(ResourceCache_purge, reporter) {
    for (bool purgable : { false, true }) {
        {
            SkResourceCache cache(1024 * 1024);
            test_duplicate_add(&cache, reporter, purgable);
        }
        {
            SkResourceCache cache(SkDiscardableMemory::Create);
            test_duplicate_add(&cache, reporter, purgable);
        }
    }
}
