/*
 * 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPicture.h"  // IWYU pragma: keep
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/private/chromium/SkDiscardableMemory.h"
#include "src/core/SkBitmapCache.h"
#include "src/core/SkCachedData.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"

#include <array>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <memory>

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

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

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(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(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(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(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 SkImages::DeferredFromPicture(recorder.finishRecordingAsPicture(),
                                                 SkISize::Make(10, 10),
                                                 nullptr,
                                                 nullptr,
                                                 SkImages::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);
        }
    }
}
