
var WebSocket   = require('ws'),
    forceUpdate = require('./force-update-app')

module.exports = {
  init: function(lrload, port) {
    var ws = lrload.client = new WebSocket('ws://127.0.0.1:' + port)
    ws.onmessage = function() {
      var src = getScriptURL()
      loadScript(src, lrload)
    }
  }
}


function getScriptURL() {
  try {
    throw new Error()
  }
  catch(e) {
    var stackLines = e.stack.split('\n')
    // chrome
    for (var i = 0; i < stackLines.length; i++){
      if (stackLines[i].match(/\(\s*http[s]?:\/\//)) {
        var mc = stackLines[i].match(/\(\s*((http[s]?:\/\/.+\/)([^\/]+\.js.*)):\d+\s*\)/)
        return mc[1].replace(/:\d+$/, '')
      }
    }
    // firefox
    for (var j = 0; j < stackLines.length; j++) {
      if (stackLines[j].match(/@http[s]?:\/\//)) {
        var mf = stackLines[j].match(/@(http[s]?:\/\/.+)/)
        // drop line and column
        var mfParts = mf[1].split(':')
        return mfParts.slice(0, mfParts.length - 2).join(':')
      }
    }
    return ''
  }
}

function cacheBust(src) {
  var uri = src.replace(/[\?&]__livereactloadPreventCache=\d+/, '')
  var idx = uri.indexOf('?')
  if (idx === -1)
    uri += '?'
  else if (idx !== uri.length - 1)
    uri += '&'
  return uri + '__livereactloadPreventCache=' + Date.now()
}

function loadScript(src, lrload) {
  var numTries = 0
  tryLoad()

  function tryLoad() {
    var script = document.createElement('script')
    script.setAttribute('src', cacheBust(src));
    script.addEventListener('error', function() {
      if (numTries < 30) {
        numTries++
        setTimeout(tryLoad, 300)
      }
    }, true)
    script.addEventListener('load', function() {
      forceUpdate(lrload)
    })
    document.getElementsByTagName('head')[0].appendChild(script)
  }
}

@@ -330,16 +330,41 @@
 URL() %7B%0A
+  return (function() %7B%0A  
   try %7B%0A
@@ -367,16 +367,18 @@
 y %7B%0A    
+  
 throw ne
@@ -389,18 +389,22 @@
 ror()%0A  
-%7D%0A
+  %7D%0A  
   catch(
@@ -408,24 +408,26 @@
 ch(e) %7B%0A    
+  
 var stackLin
@@ -455,16 +455,18 @@
 n')%0A    
+  
 // chrom
@@ -467,16 +467,18 @@
  chrome%0A
+  
     for 
@@ -516,18 +516,21 @@
 th; i++)
+ 
 %7B%0A
+  
       if
@@ -568,32 +568,34 @@
 p%5Bs%5D?:%5C/%5C//)) %7B%0A
+  
         var mc =
@@ -676,23 +676,35 @@
         
+  
 return 
+cacheBust(
 mc%5B1%5D.re
@@ -721,31 +721,38 @@
 +$/, '')
-%0A
+)%0A 
       
+ 
 %7D%0A
+  
     %7D%0A
+  
     // f
@@ -758,24 +758,26 @@
 firefox%0A    
+ 
+ 
 for (var j =
@@ -806,24 +806,26 @@
 gth; j++) %7B%0A
+  
       if (st
@@ -867,24 +867,26 @@
 ) %7B%0A        
+  
 var mf = sta
@@ -932,16 +932,18 @@
         
+ 
+ 
 // drop 
@@ -958,16 +958,18 @@
  column%0A
+  
         
@@ -1007,23 +1007,35 @@
         
+  
 return 
+cacheBust(
 mfParts.
@@ -1068,25 +1068,28 @@
 2).join(':')
-%0A
+)%0A  
       %7D%0A    
@@ -1084,26 +1084,302 @@
       %7D%0A    
+ 
+ 
 %7D%0A
+      // local files%0A      for (var k = 0; k %3C stackLines.length; k++) %7B%0A        if (stackLines%5Bk%5D.match(/file:%5C/%5C/%5C//)) %7B%0A          var fc = stackLines%5Bk%5D.match(/%5Cs*(file:%5C/%5C/%5C/.+%5C.js)(:%5Cd+)/)%0A          return fc%5B1%5D  // no cache busting for local files%0A        %7D%0A      %7D%0A  
     return '
@@ -1380,23 +1380,33 @@
 turn ''%0A
+  
   %7D%0A
-%7D%0A%0A
+  %7D)();%0A%0A  
 function
@@ -1421,24 +1421,26 @@
 st(src) %7B%0A  
+ 
+ 
 var uri = sr
@@ -1493,16 +1493,18 @@
 +/, '')%0A
+  
   var id
@@ -1524,16 +1524,18 @@
 Of('?')%0A
+  
   if (id
@@ -1544,24 +1544,26 @@
 === -1)%0A    
+ 
+ 
 uri += '?'%0A 
@@ -1561,16 +1561,18 @@
  += '?'%0A
+  
   else i
@@ -1598,24 +1598,26 @@
 th - 1)%0A    
+  
 uri += '&'%0A 
@@ -1617,16 +1617,18 @@
 = '&'%0A  
+ 
+ 
 return u
@@ -1676,17 +1676,22 @@
 e.now()%0A
-%7D
+  %7D%0A%7D%0A
 %0A%0Afuncti
@@ -1859,23 +1859,12 @@
 c', 
-cacheBust(
 src)
-)
 ;%0A  

Add support for local file bundles. #38