/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * 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.
 */
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
import image from '@ohos.multimedia.image';


import Constants from '../../../main/ets/common/Constants';
import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/cache/MemoryLruCache';
import { ImageKnifeData } from '@ohos/imageknife/src/main/ets/model/ImageKnifeData';
import { IEngineKey, ImageKnifeOption,ImageKnifeRequestSource } from '@ohos/imageknife';
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';


export default function MemoryLruCacheTest() {

  describe('MemoryLruCacheTest', () => {
    // Defines a test suite. Two parameters are supported: test suite name and test suite function.
    beforeAll(() => {
      // Presets an action, which is performed only once before all test cases of the test suite start.
      // This API supports only one parameter: preset action function.
    });
    beforeEach(() => {
      // Presets an action, which is performed before each unit test case starts.
      // The number of execution times is the same as the number of test cases defined by **it**.
      // This API supports only one parameter: preset action function.
    });
    afterEach(() => {
      // Presets a clear action, which is performed after each unit test case ends.
      // The number of execution times is the same as the number of test cases defined by **it**.
      // This API supports only one parameter: clear action function.
    });
    afterAll(() => {
      // Presets a clear action, which is performed after all test cases of the test suite end.
      // This API supports only one parameter: clear action function.
    });

    // 测试基础put,get以及size功能
    it('assertBasicFunction', 0, async () => {
      let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024);

      let data: ImageKnifeData = await getNewImageKnifeData(96)
      memoryCache.put("aaa", data)
      memoryCache.put("bbb", data)
      memoryCache.put("ccc", data)
      expect(memoryCache.size()).assertEqual(3)
      expect(memoryCache.get("aaa")).assertEqual(data)
      expect(memoryCache.get("bbb")).assertEqual(data)
      expect(memoryCache.get("ccc")).assertEqual(data)
      expect(memoryCache.size()).assertEqual(3)

      memoryCache.remove("ccc")
      memoryCache.remove("ddd")
      expect(memoryCache.size()).assertEqual(2)

      memoryCache.removeAll()
      expect(memoryCache.size()).assertEqual(0)
    });


    // 测试内存缓存size的lru功能
    it('assertSizeLruFuction', 0, async () => {
      let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024);

      let data1: ImageKnifeData = await getNewImageKnifeData(96)
      let data2: ImageKnifeData = await getNewImageKnifeData(106)
      let data3: ImageKnifeData = await getNewImageKnifeData(116)
      let data4: ImageKnifeData = await getNewImageKnifeData(126)
      let data5: ImageKnifeData = await getNewImageKnifeData(136)
      memoryCache.put("aaa", data1)
      memoryCache.put("bbb", data2)
      memoryCache.put("ccc", data3)
      memoryCache.put("ddd", data4)

      expect(memoryCache.get("aaa")).assertUndefined()
      expect(memoryCache.get("bbb")).assertEqual(data2)
      memoryCache.put("eee", data5)
      expect(memoryCache.get("ccc")).assertUndefined()
      expect(memoryCache.get("bbb")).assertEqual(data2)
      expect(memoryCache.get("ddd")).assertEqual(data4)
      expect(memoryCache.get("eee")).assertEqual(data5)
    });

    // 测试内存缓存memorySize的lru功能
    it('assertMemorySizeLruFuction', 0, async () => {
      let memoryCache: MemoryLruCache = new MemoryLruCache(3, 2 * 1024 * 1024);

      const color: ArrayBuffer = new ArrayBuffer(1024 * 1024); //96为需要创建的像素buffer大小,取值为:height * width *4
      let opts: image.InitializationOptions = {
        editable: true, pixelFormat: 3, size: {
          height: 512, width: 512
        }
      }
      let pixelmap: PixelMap = await image.createPixelMap(color, opts)
      console.info(Constants.TAG + pixelmap.getPixelBytesNumber())
      let data: ImageKnifeData = {
        source: pixelmap,
        imageWidth: 5,
        imageHeight: 5
      }

      memoryCache.put("aaa", data)
      memoryCache.put("bbb", data)
      memoryCache.get("aaa")
      memoryCache.put("ccc", data)
      expect(memoryCache.size()).assertEqual(2)
      expect(memoryCache.get("bbb")).assertUndefined()
      expect(memoryCache.get("aaa")).assertEqual(data)
      expect(memoryCache.get("ccc")).assertEqual(data)
    });

    it('memoryCacheEngineKey', 0, () => {
      let engineKey: IEngineKey = new DefaultEngineKey()
      let imageKnifeOption: ImageKnifeOption = {
        loadSrc:"abc"
      }
      let imageKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption)
      let imageAnimatorKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption,true)
      expect(imageKey == imageAnimatorKey).assertFalse()
    });

  });
}

async function getNewImageKnifeData(num:number): Promise<ImageKnifeData> {
  const color: ArrayBuffer = new ArrayBuffer(num); //96为需要创建的像素buffer大小,取值为:height * width *4
  let opts: image.InitializationOptions = {
    editable: true, pixelFormat: 3, size: {
      height: 4, width: 6
    }
  }
  let pixelmap: PixelMap = await image.createPixelMap(color, opts)

  let data: ImageKnifeData = {
    source: pixelmap,
    imageWidth: 5,
    imageHeight: 5
  }
  return data
}