import assert from 'node:assert/strict';
import { test } from 'node:test';
import { checkEdit, createMarker, draftPack, readDraft, withDraft, DRAFT_KEY } from '../src/stringPackTranslate.ts';
import { inventoryLookup, type PageInventory } from '../src/stringPacks.ts';
import { installStringPacks, type CatalogHookAdapter, type CatalogSink } from '../src/stringPackHook.ts';
const INVENTORY: PageInventory = { site: 'demo', catalog: 'web', text: 'a0000001 a0000002', message: { b0000001: 'count*' }, closed: 'c0000001' };
test('marker: strings and string results carry an invisible key marker that reads back', () => {
const marker = createMarker();
const home = marker.mark('a0000001', 'Home') as string;
const posts = (marker.mark('b0000001', (e: { count: number }) => `${e.count} posts`) as (e: unknown) => string)({ count: 3 });
assert.notEqual(home, 'Home');
assert.equal(marker.strip(home), 'Home');
assert.equal(marker.strip(posts), '3 posts');
assert.deepEqual(marker.ids(`${home} and ${posts}`), ['a0000001', 'b0000001']);
assert.deepEqual(marker.ids('no markers'), []);
const element = { element: true };
assert.equal((marker.mark('c0000001', () => element) as () => unknown)(), element, 'an element result is left alone');
assert.equal(marker.mark('x', 42), 42);
});
test('edits: checked with the pack rules; the draft is a pack applied last', () => {
const lookup = inventoryLookup(INVENTORY);
assert.equal(checkEdit(lookup, 'a0000001', 'Hejmo'), null);
assert.match(checkEdit(lookup, 'a0000001', 'x')!, /markup/);
assert.match(checkEdit(lookup, 'b0000001', '{total}')!, /not a parameter/);
assert.match(checkEdit(lookup, 'c0000001', 'x')!, /not translatable yet/);
assert.match(checkEdit(lookup, 'zzzzzzzz', 'x')!, /not in the inventory/);
const store = new Map();
const storage = { getItem: (key: string) => store.get(key) ?? null };
assert.equal(readDraft(storage), null);
assert.deepEqual(withDraft(['p1'], storage, 'demo', 'web', INVENTORY), ['p1']);
store.set(DRAFT_KEY, JSON.stringify({ language: 'eo', name: 'Mine', strings: { a0000001: 'Hejmo' } }));
const packs = withDraft(['p1'], storage, 'demo', 'web', INVENTORY);
assert.equal(packs.length, 2);
assert.deepEqual(packs[1], draftPack(readDraft(storage)!, 'demo', 'web'));
assert.equal((packs[1] as { language: string }).language, 'eo');
store.set(DRAFT_KEY, '{broken');
assert.equal(readDraft(storage), null);
});
test('translate mode hooks the catalog even without a pack and marks every value', () => {
const hooked: { sink: CatalogSink | null } = { sink: null };
const adapter: CatalogHookAdapter = { catalog: 'web', install: (_win, s) => { hooked.sink = s; return () => {}; } };
const win = { setTimeout: () => 0, clearTimeout() {} } as unknown as Window;
const marker = createMarker();
installStringPacks(win, [{ adapter, inventory: INVENTORY, packs: [] }], { mark: (id, value) => marker.mark(id, value) });
assert.ok(hooked.sink, 'hooked without packs');
const value = hooked.sink.resolve('a0000001', 'Home') as string;
assert.equal(marker.strip(value), 'Home');
assert.deepEqual(marker.ids(value), ['a0000001']);
});