// Ревью R3-2: houseplan-space-card подписывала URL подложки и выбрасывала
// результат — getCardSize() правил временную модель, а render() строил свою
// заново из конфига, поэтому <image> запрашивал сырой requires_auth-путь и на
// каждом рендере получал 401. Проверяем весь контракт подписи для этой карточки.
import { launch, checkAll, finish } from './serve.mjs';
const { page, browser } = await launch({ width: 900, height: 900 }, 1);
const res = await page.evaluate(async () => {
  const out = {};
  await customElements.whenDefined('houseplan-space-card');
  const main = window.__card;
  const raw = '/api/houseplan/content/plans/_/f1.tok.svg';

  // подложка на защищённом эндпоинте + управляемый ответ на подпись
  const cfg = JSON.parse(JSON.stringify(main._serverCfg));
  cfg.spaces = cfg.spaces.map((s) => (s.id === 'f1' ? { ...s, plan_url: raw } : s));
  let signCalls = 0;
  let failFirst = true;
  const requestedHrefs = [];
  const hass = { ...main.hass, callWS: async (m) => {
    if (m.type === 'houseplan/config/get') return { config: cfg, rev: 1 };
    if (m.type === 'houseplan/layout/get') return { layout: {} };
    if (m.type === 'houseplan/content/sign') {
      signCalls++;
      if (failFirst && signCalls === 1) throw new Error('ws down');
      const urls = {};
      for (const p of m.paths) urls[p] = p + '?authSig=SIG' + signCalls;
      return { urls };
    }
    return { ok: true };
  } };

  const host = document.createElement('div');
  document.body.appendChild(host);
  const card = document.createElement('houseplan-space-card');
  card.setConfig({ type: 'custom:houseplan-space-card', space: 'f1' });
  card.hass = hass;
  host.appendChild(card);

  const stage = async () => {
    const t0 = Date.now();
    while (!card.renderRoot?.querySelector('.hp-static-stage') && Date.now() - t0 < 6000) {
      await new Promise((r) => setTimeout(r, 60));
    }
    await card.updateComplete;
    return card.renderRoot.querySelector('.hp-static-stage svg image');
  };
  const href = async () => { const im = await stage(); return im ? im.getAttribute('href') : null; };

  // 1) первая подпись упала → сырой URL в DOM не попадает (иначе 401)
  await stage();
  await new Promise((r) => setTimeout(r, 120));
  out.hrefAfterFailedSign = await href();

  // 2) сразу повтора нет: после ошибки подпись уходит в backoff (ревью R4-2),
  //    иначе нестабильный сокет получал бы по запросу на каждый рендер
  for (let i = 0; i < 5; i++) { card.requestUpdate(); await card.updateComplete; }
  await new Promise((r) => setTimeout(r, 150));
  out.noRetryStorm = signCalls === 1;

  // 3) после выдержки повтор проходит
  await new Promise((r) => setTimeout(r, 2100));
  card.requestUpdate(); await card.updateComplete;
  await new Promise((r) => setTimeout(r, 150));
  out.hrefAfterRetry = await href();
  out.retried = signCalls === 2;

  // 4) повторный рендер не теряет подпись и не просит её заново
  const before = signCalls;
  card.requestUpdate(); await card.updateComplete;
  out.hrefStable = await href();
  out.noExtraSignOnRerender = signCalls === before;

  // 5) протухшая подпись не отдаётся, стареющая — отдаётся, пока едет замена
  const ent = card._signer.entries;
  ent[raw] = { url: raw + '?authSig=OLD', at: Date.now() - 25 * 3600 * 1000 };
  card.requestUpdate(); await card.updateComplete;
  out.hrefWhenExpired = await href();
  ent[raw] = { url: raw + '?authSig=AGING', at: Date.now() - 20 * 3600 * 1000 };
  card.requestUpdate(); await card.updateComplete;
  out.hrefWhenAging = await href();

  // ни один сырой (неподписанный) путь не должен уходить в сеть
  for (const im of card.renderRoot.querySelectorAll('image')) requestedHrefs.push(im.getAttribute('href'));
  out.noRawHrefEver = !requestedHrefs.includes(raw);
  return out;
});
// зафиксировано прогоном на v1.45.1 и сверено с кодом
checkAll(res, {
  hrefAfterFailedSign: null,
  noRetryStorm: true,
  hrefAfterRetry: '/api/houseplan/content/plans/_/f1.tok.svg?authSig=SIG2',
  retried: true,
  hrefStable: '/api/houseplan/content/plans/_/f1.tok.svg?authSig=SIG2',
  noExtraSignOnRerender: true,
  hrefWhenExpired: null,
  hrefWhenAging: '/api/houseplan/content/plans/_/f1.tok.svg?authSig=AGING',
  noRawHrefEver: true,
});
await finish(browser);
