/**
 * Module dependencies
 */

var pkg = require('../package');
var Emitter = require('emitter');
var parseLinks = require('links-parser');

// set the default api path to '/api'
var loc = window.location;
var base = loc.protocol + '//' + loc.host;
pkg.value('hyperHttpRoot', '/api');

// list of headers to check for refreshes
pkg.value('hyperHttpRefreshHeaders', [
  'location',
  'content-location'
]);

pkg.factory('hyperHttpEmitter', [
  '$http',
  function($http) {
    var subs = new Emitter();
    var external = new Emitter();

    function emitter(href, get) {
      if (href.indexOf('/') === 0) href = base + href;
      // Proxy the fn so it can be used more than once
      function handle(err, body, links) { get(err, body, links); }

      subs.on(href, handle);
      get();

      if (subs.listeners(href).length === 1) external.emit('subscribe', href);

      return function() {
        subs.off(href, handle);
        if (!subs.hasListeners(href)) external.emit('unsubscribe', href);
      };
    };

    emitter.refresh = function (href) {
      // bust the cache for everyone
      var req = {
        headers: {
          'cache-control': 'no-cache'
        },
        cache: false
      };

      $http.get(href, req)
        .success(function(body, status, headers) {
          subs.emit(href, body);
        })
        .error(function(err) {
          console.error(err.stack || err);
          // TODO send error to angular
        });
    };

    emitter.subscribe = function(fn) {
      external.on('subscribe', fn);
    };

    emitter.unsubscribe = function(fn) {
      external.on('unsubscribe', fn);
    };

    return emitter;
  }
]);

/**
 * hyper backend http service
 */

pkg.factory('hyperBackend', [
  '$http',
  'hyperHttpRoot',
  'hyperHttpEmitter',
  'hyperHttpRefreshHeaders',
  function($http, rootHref, emitter, refreshHeaders) {
    function root(fn) {
      return root.get(rootHref, fn);
    }

    root.get = function(href, fn) {
      return emitter(href, function get(body) {
        // The emitter just sent us a new response
        // We want everyone to have thier own copies as well
        if (body) return fn(null, angular.copy(body));

        $http
          .get(href, {cache: true})
          .success(function(body, status, headers) {
            var links = {};
            try {
              links = parseLinks(headers('link'));
            } catch (e) {}
            fn(null, body, links);
          })
          .error(function(err, status) {
            // Just return an empty body if it's not found
            if (status === 404) return fn();
            fn(err);
          });
      });
    };

    root.submit = function(method, action, data, fn) {
      var method = method.toUpperCase();
      var req = {method: method, url: action};

      if (method === 'GET') req.params = data;
      else req.data = data;

      $http(req)
        .success(function(body, status, headers) {
          var links = {};
          try {
            links = parseLinks(headers('link'));
          } catch (e) {}
          fn(null, body, links);

          if (method === 'GET') return;

          emitter.refresh(action);
          angular.forEach(refreshHeaders, function(header) {
            var href = headers(header);
            if (href) emitter.refresh(href);
          });
        })
        .error(function(err) {
          fn(err);
        });
    };

    return root;
  }
]);

@@ -2000,24 +2000,81 @@
 r(href, 
+get(true));%0A      function get(recurse) %7B%0A        return 
 function
  get(bod
@@ -2065,20 +2065,16 @@
 function
- get
 (body) %7B
@@ -2070,24 +2070,26 @@
 ion(body) %7B%0A
+  
         // T
@@ -2135,16 +2135,18 @@
         
+  
 // We wa
@@ -2194,24 +2194,26 @@
 ell%0A        
+  
 if (body) re
@@ -2244,24 +2244,26 @@
 py(body));%0A%0A
+  
         $htt
@@ -2274,16 +2274,18 @@
         
+  
 .get(hre
@@ -2302,16 +2302,18 @@
  true%7D)%0A
+  
         
@@ -2361,32 +2361,34 @@
 ) %7B%0A            
+ 
+ 
 var links = %7B%7D;%0A
@@ -2391,38 +2391,42 @@
 %7B%7D;%0A            
+  
 try %7B%0A
+  
               li
@@ -2464,32 +2464,34 @@
 ));%0A            
+ 
+ 
 %7D catch (e) %7B%7D%0A 
@@ -2481,32 +2481,110 @@
  %7D catch (e) %7B%7D%0A
+              if (recurse && href !== body.href) emitter(body.href, get());%0A  
             fn(n
@@ -2602,16 +2602,18 @@
 links);%0A
+  
         
@@ -2619,32 +2619,34 @@
    %7D)%0A          
+  
 .error(function(
@@ -2656,24 +2656,26 @@
 , status) %7B%0A
+  
             
@@ -2721,16 +2721,18 @@
 t found%0A
+  
         
@@ -2772,32 +2772,34 @@
 ();%0A            
+  
 fn(err);%0A       
@@ -2793,32 +2793,34 @@
 err);%0A          
+  
 %7D);%0A      %7D);%0A  
@@ -2809,27 +2809,36 @@
   %7D);%0A      
+ 
-%7D);
+ %7D;%0A      %7D
 %0A    %7D;%0A%0A   
@@ -2895,20 +2895,16 @@
 %7B%0A      
-var 
 method =

fix subscription redirects