var logger = require('./logger')
var transport = require('./transport')
var utils = require('./utils')

module.exports = {
  normalizeFrame: function normalizeFrame (frame, options) {
    options = options || {}

    if (!frame.url) return

    // normalize the frames data
    var normalized = {
      'filename': this.cleanFileUrl(frame.url),
      'lineno': frame.line,
      'colno': frame.column,
      'function': frame.func || '[anonymous]'
    }

    return normalized
  },

  traceKitStackToOpbeatException: function (stackInfo, options) {
    options = options || {}
    stackInfo.frames = []

    if (stackInfo.stack && stackInfo.stack.length) {
      stackInfo.stack.forEach(function (stack, i) {
        var frame = this.normalizeFrame(stack)
        if (frame) {
          stackInfo.frames.push(frame)
        }
      }.bind(this))
    }

    return stackInfo

  },

  cleanFileUrl: function (fileUrl) {
    if (!fileUrl) {
      fileUrl = ''
    }

    if (fileUrl.indexOf(window.location.href) > -1) {
      fileUrl = fileUrl.replace(window.location.href, '')
    }

    if (!fileUrl) {
      fileUrl = '/'
    }

    return fileUrl
  },

  processException: function processException (exception, options) {
    options = options || {}

    var stacktrace

    var type = exception.type
    var message = String(exception.message) | 'Script error'
    var lineno = exception.lineno
    var frames = exception.frames
    var fileurl = this.cleanFileUrl(exception.fileurl)

    if (frames && frames.length) {
      // Opbeat.com expects frames oldest to newest
      // and JS sends them as newest to oldest
      frames.reverse()

      stacktrace = {
        frames: frames
      }

    } else if (fileurl) {
      stacktrace = {
        frames: [{
          filename: fileurl,
          lineno: lineno
        }]
      }
    }

    // Overrride fileurl from first frame
    if (frames && frames.length && frames[0].filename) {
      fileurl = frames[0].filename
    }

    // Human readable label
    var label = lineno ? message + ' at ' + lineno : message

    var data = {
      message: label,
      culprit: fileurl,
      exception: {
        type: type,
        value: message
      },
      stacktrace: stacktrace,
      user: options.context.user || null,
      timestamp: parseInt((new Date).getTime() / 1000, 10),
      level: null,
      logger: null,
      machine: null
    }

    data.extra = this.getBrowserSpecificMetadata()

    if (options.context.extra) {
      data.data = utils.mergeObject(data.extra, options.context.extra)
    }

    logger.log('opbeat.exceptionst.processException', data)
    transport.sendToOpbeat(data, options)

  },

  getBrowserSpecificMetadata: function () {
    var viewportInfo = utils.getViewPortInfo()
    var extra = {
      'environment': {
        'utcOffset': new Date().getTimezoneOffset() / -60.0,
        'browserWidth': viewportInfo.width,
        'browserHeight': viewportInfo.height,
        'screenWidth': window.screen.width,
        'screenHeight': window.screen.height,
        'language': navigator.language,
        'userAgent': navigator.userAgent,
        'platform': navigator.platform
      },
      'page': {
        'referer': document.referrer,
        'host': document.domain,
        'location': window.location.href
      }
    }

    return extra
  }

}

@@ -1291,19 +1291,19 @@
 ception.
-typ
+nam
 e%0A    va
@@ -1341,16 +1341,17 @@
 ssage) %7C
+%7C
  'Script
@@ -1370,17 +1370,36 @@
 var 
-lineno = 
+fileurl = this.cleanFileUrl(
 exce
@@ -1404,22 +1404,24 @@
 ception.
-lineno
+fileurl)
 %0A    var
@@ -1442,24 +1442,30 @@
 ption.frames
+ %7C%7C %5B%5D
 %0A    var fil
@@ -1465,54 +1465,25 @@
 var 
-fileurl = this.cleanFileUrl(exception.
+culprit = 
 fileurl
-)
 %0A%0A  
@@ -1566,25 +1566,16 @@
 o newest
-%0A      //
  and JS 
@@ -1639,45 +1639,85 @@
     
-stacktrace = %7B%0A        frames: frames
+if (frames%5B0%5D.lineno) %7B%0A        message = message + ' at ' + frames%5B0%5D.lineno
 %0A   
@@ -1758,40 +1758,20 @@
     
-stacktrace = %7B%0A        frames: %5B
+frames.push(
 %7B%0A  
@@ -1772,26 +1772,24 @@
 h(%7B%0A        
-  
 filename: fi
@@ -1791,26 +1791,24 @@
 e: fileurl,%0A
-  
         line
@@ -1828,20 +1828,57 @@
     
-  %7D%5D%0A      %7D
+%7D)%0A    %7D%0A%0A    stacktrace = %7B%0A      frames: frames
 %0A   
@@ -1923,38 +1923,40 @@
 t frame%0A    if (
-frames
+!fileurl
  && frames.lengt
@@ -1978,16 +1978,23 @@
 filename
+.length
 ) %7B%0A    
@@ -2035,98 +2035,8 @@
  %7D%0A%0A
-    // Human readable label%0A    var label = lineno ? message + ' at ' + lineno : message%0A%0A
     
@@ -2067,13 +2067,15 @@
 ge: 
-label
+message
 ,%0A  
@@ -2087,23 +2087,23 @@
 ulprit: 
-fileurl
+culprit
 ,%0A      

Update exception payload to match Opbeat API.