// Adstop — YouTube: вырезание рекламных вставок из данных плеера.
// Работает в MAIN world на document_start: перехватывает JSON.parse,
// Response.json и присваивание ytInitialPlayerResponse, удаляя из ответов
// поля с рекламой (adPlacements/adSlots/playerAds) до того, как их увидит плеер.
// Тот же принцип используют uBlock Origin (json-prune) и AdGuard.
(() => {
  if (window.__adstopYtPrune) return;
  window.__adstopYtPrune = true;

  const AD_KEYS = ["adPlacements", "adSlots", "playerAds", "adBreakHeartbeatParams"];
  let active = true;
  let prunedCount = 0;

  // companion-скрипт (isolated world) может выключить нас (белый список/подписка)
  window.addEventListener("adstop-yt-state", (event) => {
    active = event.detail !== false;
  });
  // и спросить статистику
  window.addEventListener("adstop-yt-stats-request", () => {
    window.dispatchEvent(new CustomEvent("adstop-yt-stats", { detail: prunedCount }));
  });

  function prune(value) {
    if (!active || value === null || typeof value !== "object") return value;
    try {
      let hit = false;
      for (const key of AD_KEYS) {
        if (key in value) {
          delete value[key];
          hit = true;
        }
      }
      if (hit) prunedCount += 1;
      // плеер иногда оборачивает ответ: { playerResponse: {...} }
      if (value.playerResponse && typeof value.playerResponse === "object") {
        prune(value.playerResponse);
      }
    } catch {
      // чужие экзотические объекты не трогаем
    }
    return value;
  }

  const originalParse = JSON.parse;
  JSON.parse = function adstopParse(...args) {
    return prune(originalParse.apply(this, args));
  };

  const originalJson = Response.prototype.json;
  Response.prototype.json = function adstopJson(...args) {
    return originalJson.apply(this, args).then(prune);
  };

  // страница делает `var ytInitialPlayerResponse = {...}` — ловим присваивание
  let initialPlayerResponse;
  try {
    Object.defineProperty(window, "ytInitialPlayerResponse", {
      configurable: true,
      get: () => initialPlayerResponse,
      set: (value) => {
        initialPlayerResponse = prune(value);
      },
    });
  } catch {
    // свойство уже определено — значит, мы опоздали; JSON.parse-хук всё равно работает
  }
})();
