(function () {
  "use strict";

  //
  // Link tracking
  //

  var PROTOCOL_REGEX = /^(\w+:)/;

  function getAbsoluteUrl(url) {
    var trimmedUrl = url.trim();
    // Trim quote characters
    trimmedUrl = trimmedUrl.replace(/^['"]+/, "").replace(/['"]+$/, "");
    if (trimmedUrl.match(PROTOCOL_REGEX)) {
      // url is already absolute
      return trimmedUrl;
    }
    return window.location.protocol + "//" + window.location.host
      + trimmedUrl.replace(/;jsessionid=[A-Z0-9]*/, '').replace(/fwdsess=1&/, '').replace(/fwdsessionid=[A-Z0-9]*&/, '');
  }

  //  search for a document title in the vicinity of a given element
  function getDocumentTitleForElement(element) {
    var $element = jQuery(element);
    // TODO: What the...? Don't do this global assignment!
    window.el = $element;
    // get title from document box, if inside a document list
    var title = $element.closest('.DocumentBox').find('.DocumentTitle').get(0);
    if (!title) {
      // we're probably inside a landing page, get the title from there
      title = jQuery('#LandingPage_title').get(0);
    }
    return title ? title.textContent.trim() : '';
  }

  // track a link on a document instance (e.g. shortinstructions)
  function trackDocumentInstanceView(event) {
    var link = event.currentTarget;
    var title = getDocumentTitleForElement(link);
    var url = link.pathname + link.search;
    var isJavaScriptLink = -1 !== link.protocol.toLowerCase().indexOf("javascript:");
    var isDispatchUrl = url.indexOf('/dispatch.do') >= 0;
    if (isDispatchUrl || isJavaScriptLink) {
      // if url is pointing to the deeplink dispatcher, tracking will be done there
      return;
    }
    var instanceType = 'other';
    var documentTypeName = '';
    if (link.dataset) {
      instanceType = link.dataset.instanceType;
      documentTypeName = link.dataset.documentTypeName || '';
    }
    statisticsProviders.forEach(function (provider) {
      if (typeof provider.trackDocumentInstanceView === 'function') {
        provider.trackDocumentInstanceView({
          instanceType: instanceType,
          url: getAbsoluteUrl(url),
          title: title,
          documentTypeName: documentTypeName
        });
      }
    });
  }

  // add event hooks for clicking on document instances (e.g. shortinstructions)
  function addClickEventHandlers() {
    var $links;
    $links = jQuery('a[data-instance-type]');
    $links.off('click', trackDocumentInstanceView);
    $links.click(trackDocumentInstanceView);
  }

  // track links clicked inside a QuickAccess result page
  function trackQuickAccessClick(props) {
    statisticsProviders.forEach(function (provider) {
      if (typeof provider.trackQuickAccessClick === 'function') {
        provider.trackQuickAccessClick({
          type: props.type,
          instanceType: props.instanceType,
          documentTypeName: props.documentTypeName || '',
          url: getAbsoluteUrl(props.url),
          title: props.title,
          pscName: props.pscName
        });
      }
    });
  }

  // on window load, setup event hooks for
  // - opening landing pages and
  // - document instance clicks

  function init() {
    if (typeof statisticsProviders === 'undefined' || statisticsProviders.length === 0) {
      return;
    }
    // track clicks on document instances inside document lists of structure views
    addClickEventHandlers();
    var originalLandingPageCallback = window.openLandingPageCallback || function () {
    };
    // hook into openLandingPageCallback to set link click hooks once a landing page has loaded
    window.openLandingPageCallback = function () {
      var args = [].slice.call(arguments);
      // the original callback must run first, as it sets up the landing page
      var returnValue = originalLandingPageCallback.apply(window, args);
      // be as unobtrusive as possible; return result of original function directly
      // and add click handlers in async thread
      window.setTimeout(addClickEventHandlers, 0);
      return returnValue;
    }
  }

  if (document.readyState === 'complete') {
    init();
  } else {
    // delay initialization until whole page has been loaded
    // ensures that jQuery and all DOM elements are available
    window.addEventListener('load', init);
  }

  // Exports:
  // trackQuickAccessClick() is used by the QuickAccess result pages directly,
  // so we add it into the global namespace
  window.trackQuickAccessClick = trackQuickAccessClick;

})();
