import {test, expect, vi} from 'vitest';
import fs from 'fs';
import path from 'path';
import {RequestManager} from '../util/request_manager.ts';
import {loadGlyphRange} from './load_glyph_range.ts';
import {fakeServer} from 'nise';
import {bufferToArrayBuffer, sleep} from '../util/test/util.ts';

test('loadGlyphRange', async ()  => {
    global.fetch = null;

    const transform = vi.fn().mockImplementation((url) => {
        return {url};
    });

    const manager = new RequestManager(transform);

    const server = fakeServer.create();
    server.respondWith(bufferToArrayBuffer(fs.readFileSync(path.join(__dirname, '../../test/unit/assets/0-255.pbf'))));

    const promise = loadGlyphRange('Arial Unicode MS', 0, 'https://localhost/fonts/v1/{fontstack}/{range}.pbf', manager);
    await sleep(0);
    server.respond();
    const result = await promise;

    expect(transform).toHaveBeenCalledTimes(1);
    expect(transform).toHaveBeenCalledWith('https://localhost/fonts/v1/Arial Unicode MS/0-255.pbf', 'Glyphs');

    expect(Object.keys(result)).toHaveLength(223);
    for (const key in result) {
        const id = Number(key);
        const glyph = result[id];

        expect(glyph.id).toBe(Number(id));
        expect(glyph.metrics).toBeTruthy();
        expect(glyph.metrics.width).toBeTypeOf('number');
        expect(glyph.metrics.height).toBeTypeOf('number');
        expect(glyph.metrics.top).toBeTypeOf('number');
        expect(glyph.metrics.advance).toBeTypeOf('number');
    }
    expect(server.requests[0].url).toBe('https://localhost/fonts/v1/Arial Unicode MS/0-255.pbf');
});

test('loadGlyphRange with async transformRequest', async () => {
    global.fetch = null;

    const manager = new RequestManager(async (url) => ({
        url,
        headers: {Authorization: 'Bearer token'}
    }));

    const server = fakeServer.create();
    server.respondWith(bufferToArrayBuffer(fs.readFileSync(path.join(__dirname, '../../test/unit/assets/0-255.pbf'))));

    const promise = loadGlyphRange('Arial Unicode MS', 0, 'https://localhost/fonts/v1/{fontstack}/{range}.pbf', manager);
    await sleep(0);
    server.respond();
    const result = await promise;

    expect(Object.keys(result)).toHaveLength(223);
    for (const key in result) {
        const id = Number(key);
        const glyph = result[id];

        expect(glyph.id).toBe(Number(id));
        expect(glyph.metrics).toBeTruthy();
        expect(glyph.metrics.width).toBeTypeOf('number');
        expect(glyph.metrics.height).toBeTypeOf('number');
        expect(glyph.metrics.top).toBeTypeOf('number');
        expect(glyph.metrics.advance).toBeTypeOf('number');
    }
    expect(server.requests[0].url).toBe('https://localhost/fonts/v1/Arial Unicode MS/0-255.pbf');
    expect(server.requests[0].requestHeaders.Authorization).toBe('Bearer token');
});
