// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { assert } from 'chai';
import * as Trace from '../../../models/trace/trace.js';
import { defaultTraceEvent } from '../../../testing/TraceHelpers.js';
import * as Utils from './utils.js';
const { cacheForTesting, emitter, getOrQueue, loadImageForTesting: loadImage, preload } = Utils.ImageCache;
describe('ImageCache', () => {
    // Generate at https://yulvil.github.io/gopherjs/02/ with 1,1,1,jpeg in the form fields
    const validJpegData = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGISWfUPEAAA//8CmgG/YtkszwAAAABJRU5ErkJggg==';
    const rawSourceEvent = {
        ...defaultTraceEvent,
        id: '0x1',
        args: { snapshot: validJpegData },
        name: "Screenshot" /* Trace.Types.Events.Name.SCREENSHOT */,
        cat: 'disabled-by-default-devtools.screenshot',
        ph: "O" /* Trace.Types.Events.Phase.OBJECT_SNAPSHOT */,
    };
    Trace.Handlers.ModelHandlers.Screenshots.reset();
    Trace.Handlers.ModelHandlers.Screenshots.handleEvent(rawSourceEvent);
    void Trace.Handlers.ModelHandlers.Screenshots.finalize();
    const syntheticScreenshot1 = Trace.Handlers.ModelHandlers.Screenshots.data().legacySyntheticScreenshots?.at(0);
    assert.isOk(syntheticScreenshot1);
    const syntheticScreenshot2 = structuredClone(syntheticScreenshot1);
    syntheticScreenshot2.rawSourceEvent.id = '0x2';
    const badDataUriScreenshot = structuredClone(syntheticScreenshot1);
    badDataUriScreenshot.args.dataUri = 'INVALIDDATA';
    beforeEach(() => {
        const cache = cacheForTesting;
        cache.delete(syntheticScreenshot1);
        cache.delete(syntheticScreenshot2);
        cache.delete(badDataUriScreenshot);
    });
    it('loadImage resolves valid images', async () => {
        const datauri = `data:image/jpg;base64,${validJpegData}`;
        const res = await loadImage(datauri);
        assert.instanceOf(res, HTMLImageElement);
    });
    it('loadImage resolves invalid images to null', async () => {
        const datauri = 'data:image/jpg;base64,INVALIDDATA';
        const res = await loadImage(datauri);
        assert.isNull(res);
    });
    it('getOrQueue should return null for a new screenshot', () => {
        assert.isNull(getOrQueue(syntheticScreenshot1));
    });
    it('getOrQueue should return the same image for the same screenshot', async () => {
        // Preload to ensure image is loaded for both reads.
        await preload([syntheticScreenshot1]);
        const image1 = getOrQueue(syntheticScreenshot1);
        const image2 = getOrQueue(syntheticScreenshot1);
        assert.strictEqual(image2, image1);
        assert.instanceOf(image1, HTMLImageElement);
    });
    it('emitter should emit an event when a screenshot is updated', async () => {
        const { promise, resolve } = Promise.withResolvers();
        emitter.addEventListener('screenshot-loaded', ev => {
            const event = ev;
            assert.strictEqual(event.detail.screenshot, syntheticScreenshot1);
            assert.instanceOf(event.detail.image, HTMLImageElement);
            // Cache is updated too.
            assert.instanceOf(getOrQueue(syntheticScreenshot1), HTMLImageElement);
            resolve(null);
        }, { once: true });
        assert.isNull(getOrQueue(syntheticScreenshot1));
        return await promise;
    });
    it('getOrQueue should return null (immediately and eventually) for an invalid image', async () => {
        // First attempt is null because empty cache.
        assert.isNull(getOrQueue(badDataUriScreenshot));
        const { promise, resolve } = Promise.withResolvers();
        emitter.addEventListener('screenshot-loaded', ev => {
            const event = ev;
            assert.strictEqual(event.detail.screenshot, badDataUriScreenshot);
            // Loaded but invalid, so null.
            assert.isNull(event.detail.image);
            // Null stored in the cache
            assert.isNull(getOrQueue(badDataUriScreenshot));
            resolve(null);
        }, { once: true });
        return await promise;
    });
    it('preload should load all screenshots', async () => {
        await preload([syntheticScreenshot1, syntheticScreenshot2]);
        assert.instanceOf(getOrQueue(syntheticScreenshot1), HTMLImageElement);
        assert.instanceOf(getOrQueue(syntheticScreenshot2), HTMLImageElement);
    });
});
//# sourceMappingURL=ImageCache.test.js.map