/*
 * Copyright (C) 2019 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.
 */
package com.android.wallpaper.asset;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.LruCache;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityManagerCompat;

import java.util.Objects;

/**
 * Implementation of {@link Asset} that wraps another {@link Asset} but keeps an LRU cache of
 * bitmaps generated by {@link #decodeBitmap(int, int, BitmapReceiver)} to avoid having to decode
 * the same bitmap multiple times.
 * The cache key is the wrapped Asset and the target Width and Height requested, so that we only
 * reuse bitmaps of the same size.
 */
public class BitmapCachingAsset extends Asset {

    private static class CacheKey {
        final Asset asset;
        final int width;
        final int height;

        CacheKey(Asset asset, int width, int height) {
            this.asset = asset;
            this.width = width;
            this.height = height;
        }

        @Override
        public int hashCode() {
            return Objects.hash(asset, width, height);
        }

        @Override
        public boolean equals(Object obj) {
            return obj instanceof CacheKey
                    && ((CacheKey)obj).asset == this.asset
                    && ((CacheKey)obj).width == this.width
                    && ((CacheKey)obj).height == this.height;
        }
    }

    private static int cacheSize = 100 * 1024 * 1024; // 100MiB
    private static LruCache<CacheKey, Bitmap> sCache = new LruCache<CacheKey, Bitmap>(cacheSize) {
        @Override protected int sizeOf(CacheKey key, Bitmap value) {
            return value.getByteCount();
        }
    };

    private final boolean mIsLowRam;
    private final Asset mOriginalAsset;

    public BitmapCachingAsset(Context context, Asset originalAsset) {
        mOriginalAsset = originalAsset;
        mIsLowRam = ActivityManagerCompat.isLowRamDevice(
                (ActivityManager) context.getApplicationContext().getSystemService(
                        Context.ACTIVITY_SERVICE));
    }

    @Override
    public void decodeBitmap(int targetWidth, int targetHeight, BitmapReceiver receiver) {
        // Skip the cache in low ram devices
        if (mIsLowRam) {
            mOriginalAsset.decodeBitmap(targetWidth, targetHeight, receiver::onBitmapDecoded);
            return;
        }
        CacheKey key = new CacheKey(mOriginalAsset, targetWidth, targetHeight);
        Bitmap cached = sCache.get(key);
        if (cached != null) {
            receiver.onBitmapDecoded(cached);
        } else {
            mOriginalAsset.decodeBitmap(targetWidth, targetHeight, bitmap -> {
                if (bitmap != null) {
                    sCache.put(key, bitmap);
                }
                receiver.onBitmapDecoded(bitmap);
            });
        }
    }

    @Override
    public void decodeBitmapRegion(Rect rect, int targetWidth, int targetHeight,
            BitmapReceiver receiver) {
        mOriginalAsset.decodeBitmapRegion(rect, targetWidth, targetHeight, receiver);
    }

    @Override
    public void decodeRawDimensions(@Nullable Activity activity, DimensionsReceiver receiver) {
        mOriginalAsset.decodeRawDimensions(activity, receiver);
    }

    @Override
    public boolean supportsTiling() {
        return mOriginalAsset.supportsTiling();
    }
}
