/* globals googletag URI */
import run from 'ember-runloop';

class GoogleTag {
  cmd(callback) {
    googletag.cmd.push(callback);
  }

  constructor() {
    this.campaign = URI().query(true).campaign;

    let pubads = googletag.pubads();
    pubads.enableSingleRequest();
    pubads.disableInitialLoad();

    this.cmd(() => {
      googletag.enableServices();
    });
  }

  /**
   *
   * Creates an ad slot.
   *
   * adUnitPath - Full path of the ad unit with the network code and unit code.
   *
   * size - Width and height of the added slot. This is the size that is used
   *        in the ad request if no responsive size mapping is provided or the
   *        size of the viewport is smaller than the smallest size provided in
   *        the mapping.
   *
   * div - ID of the div that will contain this ad unit.
   *
   * targetingParams (Optional) - Targeting parameters to be set on the slot
   *                              using `slot.setTargeting()`.
   *
   * Also refer to googletag documentation, specifically defineSlot:
   *
   * https://developers.google.com/doubleclick-gpt/reference#googletag.defineSlot
   */
  createSlot({ adUnitPath, size, div, targetingParams }) {
    let slot = googletag.defineSlot(adUnitPath, size, div);
    slot.addService(googletag.pubads());

    //
    // If you're considering refactoring this code to set parameters at the
    // service level (with `googletag.pubads().setTargeting`), be warned:
    //
    // 1. I'm not sure it gives us any benefits.
    // 2. Rails clears all the targeting on the service from time to time:
    //
    // https://git-aws.internal.justin.tv/web/web/blob/03206fd/app/assets/javascripts/twitch/asyncAds.js#L87
    //

    if (targetingParams) {
      Object.keys(targetingParams).forEach(k => {
        slot.setTargeting(k, targetingParams[k]);
      });

      if (this.campaign && !targetingParams.campaign) {
        slot.setTargeting('campaign', this.campaign);
      }
    }

    googletag.display(div);
    run.scheduleOnce('afterRender', this, this.refreshSlots);
    return slot;
  }

  refreshSlots() {
    googletag.pubads().refresh();
  }

  destroySlots() {
    googletag.destroySlots(...arguments);
  }

  destroySlot(slot) {
    this.destroySlots([slot]);
  }
}

class FakeGoogleTag {
  constructor() {
    this.isBlocked = true;
  }

  cmd() {}
  createSlot() {}
  refreshSlots() {}
  destroySlots() {}
  destroySlot() {}
}


export default function initializeGoogleTag() {
  // These conditions check for various ad blockers:
  //
  // AdBlock Plus: `googletag` or `googletag.pubads` is removed.
  // uBlock Origin: replaces `getVersion` to return ''
  if (
    !googletag ||
    !googletag.pubads ||
    !googletag.getVersion ||
    googletag.getVersion() === '') {
    return new FakeGoogleTag();
  }

  return new GoogleTag();
}
