/*global URI*/
// This is a js mirror of some of the rails routes for pages.
//
// Depends on twitch.core.js

(function (Twitch, $) {

  var routes = {
    channel: '/:1',
    team: '/team/:1',
    profile: '/:1/profile',
    vod: '/:1/v/:2',
    game: '/directory/game/:1',
    gameVideos: '/directory/game/:1/videos/week',
    message: '/message/show/:1',
    compose: '/message/compose?to=:1',
    productDoNotRenew: '/products/:1/ticket/edit',
    productCancel: '/products/:1/ticket/edit?cancel=true',
    productCancelAndRefund: '/products/:1/ticket/edit?cancel=true&refund=true',
    profileBanner: '/api/channels/:1/profile_banner',
    gameBoxArtJpg: 'https://static-cdn.jtvnw.net/ttv-boxart/:1-138x190.jpg',
    jtvChannel: 'http://www.justin.tv/:1',
    dashboards: '/:1/dashboard/:2',
    manager: '/:1/manager',
    highlightVod: '/:1/manager/:2/highlight',
    subscribe: '/:1/subscribe?ref=:2',
    // Cannot be HTTPS, the certificate for media.steampowered.com is invalid
    csGoSkillImg: 'https://steamcdn-a.akamaihd.net/apps/csgo/images/skillgroups/skillgroup:1.png'
  };

  var constructUri = function (uri, segments) {
    segments.forEach(function (segment, index) {
      uri = uri.replace(":" + (index + 1), encodeURIComponent(segment), "g");
    });
    if (uri.match(/:\d/)) {
      throw new Error('Not enough arguments provided to construct this uri');
    }
    return uri;
  };

  var uri = {};
  var url = {};
  var canonicalUrl = {};

  _.each(routes, function (uriPattern, name) {
    uri[name] = function () {
      return constructUri(uriPattern, _.toArray(arguments));
    };
    url[name] = function () {
      return URI().protocol() + "://" + window.location.host + constructUri(uriPattern, _.toArray(arguments));
    };
    canonicalUrl[name] = function () {
      return "https://www.twitch.tv" + constructUri(uriPattern, _.toArray(arguments));
    };
  });

  var _url_params = _.memoize(function (params) {
    return _.reduce(decodeURIComponent(params).split("&"), function (memo, param) {
      var data = memo,
          pieces = param.split("="),
          key = pieces[0],
          keys = [],
          value = pieces[1];

      // This nasty piece of work turns "a[b][c][d]" into ["a", "b", "c", "d"]
      while (key) {
        var d = /^(.+?)(?:\[(.*?)\])?((?:\[.*?\])*)$/.exec(key);
        keys.push(d[1]);
        if (d[2]) {
          key = d[2] + d[3];
        } else {
          key = "";
        }
      }

      // All but the last key...
      _.each(_.initial(keys), function (key) {
        data[key] = data[key] || {};
        data = data[key];
      });

      // Set the actual value
      data[_.last(keys)] = value;
      return memo;
    }, {});
  });

  var url_params = function (params) {
    return _url_params(params || URI().query());
  };

  Twitch.mixin({
    uri: uri,
    url: url,
    canonicalUrl: canonicalUrl,
    url_params: url_params
  });

})(Twitch, jQuery);
