/*!

* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/

/**

* Module exports.
*/

module.exports = callSiteToString

/**

* Format a CallSite file location to a string.
*/

function callSiteFileLocation(callSite) {

var fileName
var fileLocation = ''

if (callSite.isNative()) {
  fileLocation = 'native'
} else if (callSite.isEval()) {
  fileName = callSite.getScriptNameOrSourceURL()
  if (!fileName) {
    fileLocation = callSite.getEvalOrigin()
  }
} else {
  fileName = callSite.getFileName()
}

if (fileName) {
  fileLocation += fileName

  var lineNumber = callSite.getLineNumber()
  if (lineNumber != null) {
    fileLocation += ':' + lineNumber

    var columnNumber = callSite.getColumnNumber()
    if (columnNumber) {
      fileLocation += ':' + columnNumber
    }
  }
}

return fileLocation || 'unknown source'

}

/**

* Format a CallSite to a string.
*/

function callSiteToString(callSite) {

var addSuffix = true
var fileLocation = callSiteFileLocation(callSite)
var functionName = callSite.getFunctionName()
var isConstructor = callSite.isConstructor()
var isMethodCall = !(callSite.isToplevel() || isConstructor)
var line = ''

if (isMethodCall) {
  var methodName = callSite.getMethodName()
  var typeName = getConstructorName(callSite)

  if (functionName) {
    if (typeName && functionName.indexOf(typeName) !== 0) {
      line += typeName + '.'
    }

    line += functionName

    if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) {
      line += ' [as ' + methodName + ']'
    }
  } else {
    line += typeName + '.' + (methodName || '<anonymous>')
  }
} else if (isConstructor) {
  line += 'new ' + (functionName || '<anonymous>')
} else if (functionName) {
  line += functionName
} else {
  addSuffix = false
  line += fileLocation
}

if (addSuffix) {
  line += ' (' + fileLocation + ')'
}

return line

}

/**

* Get constructor name of reviver.
*/

function getConstructorName(obj) {

var receiver = obj.receiver
return (receiver.constructor && receiver.constructor.name) || null

}