/*jshint bitwise:false, evil:true, maxlen: 279*/
/*global console, adnxs, googletag, escape */
(function (Twitch, $) {
  var ads = {},
    DFP_NETWORK_CODE = '3576121';

  // Adding a ?force_<integrationName>_display to the URL forces Twitch.ads to serve a
  // specific type of ad integration. For example twitch.tv/minigolf2000/?force_sevenone_display
  // shows SevenOne ads on minigolf2000's channel page. This is useful for testing.
  // We compute this value and store it here because some dynamic pages (like the directory)
  // strip the URL param when the user takes actions on the page
  var cachedQueryParam = window.location.toString();

  var DEPRECATED = "Deprecation warning: use the asynchronous Twitch.asyncAds.ready(..)";
  var printDeprecation = function () { console.debug(DEPRECATED); };
  
  var interpolateUrlParams = function (url, options) {
    var key;
    var keys = Object.keys(options);
    for (var i = 0, length = keys.length; i < length; i++) {
      key = keys[i];
      url = url.replace('{{' + key + '}}', encodeURIComponent(options[key]));
    }
    return url;
  };

  ads.ready = function (callback) {
    var userPromise = new RSVP.Promise(function (resolve) {
      Twitch.user(function (userData) {
        resolve(_.pick(userData, 'has_turbo'));
      }, function () {
        resolve(false);
      });
    });
    RSVP.all([userPromise, Twitch.geo]).then(function (resolutions) {
      var userData = resolutions[0];
      var geo = resolutions[1].geo;

      // TODO: how do we check the current channel subscription / whether you're the channel owner?
      var enabled = !userData || !userData['has_turbo'];

      callback(ads._readyData = {
        geo: geo,
        enabled: enabled
      });
    });
  };

  ads.enabled = function () {
    if (ads._readyData) {
      return ads._readyData.enabled;
    } else {
      printDeprecation();
      return !PP.turbo;
    }
  };

  ads.fetchAll = function () {
    if (Twitch.ads.enabled()) {
      googletag.cmd.push(function () {
        googletag.pubads().refresh();
      });
    }
  };

  var googleTagCalls = [];

  ads.pushGoogleTag = function (slot, dimensions, hideHolder) {
    googleTagCalls.push(function () {
      var unitName = Twitch.ads.dfpSlotPath(ads.dfpSlotName()),
        divId = slot + "_holder";

      googletag.pubads().setTargeting('pagetype', ads.dfpPageType());
      googletag.defineSlot(unitName, dimensions, divId).addService(googletag.pubads());
      googletag.cmd.push(function () {
        googletag.pubads().setTargeting("salt", window.location.protocol === 'https:' ? 'true' : 'false');
        googletag.display(slot + "_holder");
      });

      if (hideHolder) {
        $('#' + slot + "_holder").hide();
      }
    });
  };

  ads.registerGoogleTags = function () {
    googleTagCalls.forEach(function (googleTagCall) {
      googletag.cmd.push(googleTagCall);
    });
  };

  ads.slotName = function (slot) {
    return "Twitch_" + slot;
  };


  var _prepareAdSections = {};

  _prepareAdSections.leader = function (adSlotName) {
    if (!Twitch.ads.enabled()) {
      return;
    }

    if (Twitch.ads.enabled()) {
      Twitch.ads.pushGoogleTag(adSlotName, [[970, 66], [728, 90]]);
    }

    Twitch.asyncAds.ready(function () {
      $('.ad_leader').addClass('dfp'); // for styling
      // Take note that 'dfp' provides no set of styles to it's root element. It's unclear exactly what purpose
      // adding this class serves. Did not have time to investigate this fully LB 1/6/16
    });
  };

  _prepareAdSections.pushdown = function (adSlotName) {
    if (Twitch.ads.enabled()) {
      Twitch.ads.pushGoogleTag(adSlotName, [[970, 418], [970, 67], [970, 250], [970, 150], [980, 250]], true);
    }

    Twitch.asyncAds.ready(function () {
      $('.fp_opa_pushdown').addClass('dfp'); // for styling
      // Take note that 'dfp' provides no set of styles to it's root element. It's unclear exactly what purpose
      // adding this class serves. Did not have time to investigate this fully LB 1/6/16
    });
  };

  _prepareAdSections.rectangle = function (adSlotName) {
    if (!Twitch.ads.enabled()) {
      $('.advertisement').hide();
      $('.ad_contain').hide();
      return;
    }

    var showAd = function () {
      if (window.SitePageType === 'directory') {
        $('.ad_contain .advertisement').show();
        $('#' + adSlotName + '_holder .adFrame').css('height', '250px');
        $('.ad_contain').show();
      }
    };

    if (Twitch.ads.enabled()) {
      // google success callback specified in ad.js
      Twitch.ads.pushGoogleTag(adSlotName, [[300, 250], [300, 600], [250, 600]]);
    }
  };

  _prepareAdSections.siteskin = function (adSlotName) {
    if (Twitch.ads.enabled()) {
      Twitch.ads.pushGoogleTag(adSlotName, [1, 1], true);
    }
  };

  ads.prepareAd = function (adSlotName, sectionName) {
    var twitchAdSlotName = Twitch.ads.slotName(adSlotName);
    if (_prepareAdSections[sectionName]) {
      _prepareAdSections[sectionName](twitchAdSlotName);
    }
  };

  ads.hls = {
    formatGame: function (value) {
      return (value || '').toLowerCase().replace(/[^a-z0-9]+/g, '_');
    },
    stripAmpEq: function (value) {
      return value.replace(/[&=]/g, '');
    },
    getAdTagUrl: function (options) {
      var URL_TEMPLATE, CUSTOM_TEMPLATE;
      switch (options.provider) {
      case 'twitch':
        URL_TEMPLATE =
          'http://pubads.g.doubleclick.net/gampad/ads' +
          '?sz=640x480&ad_rule=0&gdfp_req=1&iu=/{{dfpNetworkCode}}/twitch/channels/{{channel}}&ciu_szs=300x250' +
          '&url={{referrer}}&correlator={{timestamp}}&env=vp&unviewed_position_start=1&output=xml_vast3&cust_params={{custom}}';
        CUSTOM_TEMPLATE = 'chan={{channel}}&timebreak=30&game={{game}}&platform={{platform}}&mature=true&pos=pre';
        return interpolateUrlParams(URL_TEMPLATE, {
          channel: options.channel,
          referrer: options.referrer,
          timestamp: new Date().getTime(),
          dfpNetworkCode: DFP_NETWORK_CODE,
          custom: interpolateUrlParams(CUSTOM_TEMPLATE, {
            channel: Twitch.ads.hls.stripAmpEq(options.channel),
            game: Twitch.ads.hls.formatGame(options.game),
            platform: options.platform ? Twitch.ads.hls.stripAmpEq(options.platform) : 'html5'
          })
        });
      case 'test':
        return 'http://pubads.g.doubleclick.net/gampad/ads' +
        '?sz=400x300&iu=%2F6062%2Fiab_vast_samples&ciu_szs=300x250%2C728x90&impl=s&gdfp_req=1&env=vp&output=xml_vast3' +
        '&unviewed_position_start=1&url=[referrer_url]&correlator=[timestamp]&cust_params=iab_vast_samples%3Dlinear';
      }
    }
  };

  // For custom targeting parameter 'pagetype'
  ads.dfpPageType = function () {
    switch (window.SitePageType) {
    case 'front_page':
      return 'homepage';
    case 'search':
      return 'search';
    default:
      console.error("TWITCH: Set a DFP page type");
      return '';
    }
  };

  // The full path "/3576121/twitch/SLOT_NAME"
  ads.dfpSlotPath = function (slotName) {
    return '/' + DFP_NETWORK_CODE + '/twitch/' + slotName;
  };

  // For slot name: /3576121/twitch/NAME
  ads.dfpSlotName = function () {
    switch (window.SitePageType) {
    case 'front_page':
      return 'homepage';
    case 'search':
      return 'directory';
    default:
      console.error("TWITCH: Set a DFP page type");
      return '';
    }
  };

  ads.dfpNetworkCode = DFP_NETWORK_CODE;

  Twitch.mixin({
    ads: ads
  });

})(Twitch, jQuery);
