// Load our dependencies
var stringify = require('../common/stringify')

// Define our context Karma constructor
function ContextKarma (callParentKarmaMethod) {
  // Define local variables
  var hasError = false
  var self = this
  var isLoaded = false

  // Define our loggers
  // DEV: These are intentionally repeated in client and context
  this.log = function (type, args) {
    var values = []

    for (var i = 0; i < args.length; i++) {
      values.push(this.stringify(args[i], 3))
    }

    this.info({ log: values.join(', '), type: type })
  }

  this.stringify = stringify

  // Define our proxy error handler
  // DEV: We require one in our context to track `hasError`
  this.error = function () {
    hasError = true
    callParentKarmaMethod('error', [].slice.call(arguments))
    return false
  }

  // Define our start handler
  function UNIMPLEMENTED_START () {
    this.error('You need to include some adapter that implements __karma__.start method!')
  }
  // all files loaded, let's start the execution
  this.loaded = function () {
    // has error -> cancel
    if (!hasError && !isLoaded) {
      isLoaded = true
      try {
        this.start(this.config)
      } catch (error) {
        this.error(error.stack || error.toString())
      }
    }

    // remove reference to child iframe
    this.start = UNIMPLEMENTED_START
  }
  // supposed to be overriden by the context
  // TODO(vojta): support multiple callbacks (queue)
  this.start = UNIMPLEMENTED_START

  // Define proxy methods
  // DEV: This is a closured `for` loop (same as a `forEach`) for IE support
  var proxyMethods = ['complete', 'info', 'result']
  for (var i = 0; i < proxyMethods.length; i++) {
    (function bindProxyMethod (methodName) {
      self[methodName] = function boundProxyMethod () {
        callParentKarmaMethod(methodName, [].slice.call(arguments))
      }
    }(proxyMethods[i]))
  }

  // Define bindings for context window
  this.setupContext = function (contextWindow) {
    // If we clear the context after every run and we already had an error
    //   then stop now. Otherwise, carry on.
    if (self.config.clearContext && hasError) {
      return
    }

    // Perform window level bindings
    // DEV: We return `self.error` since we want to `return false` to ignore errors
    contextWindow.onerror = function () {
      return self.error.apply(self, arguments)
    }
    // DEV: We must defined a function since we don't want to pass the event object
    contextWindow.onbeforeunload = function (e, b) {
      callParentKarmaMethod('onbeforeunload', [])
    }

    contextWindow.dump = function () {
      self.log('dump', arguments)
    }

    var _confirm = contextWindow.confirm
    var _prompt = contextWindow.prompt

    contextWindow.alert = function (msg) {
      self.log('alert', [msg])
    }

    contextWindow.confirm = function (msg) {
      self.log('confirm', [msg])
      return _confirm(msg)
    }

    contextWindow.prompt = function (msg, defaultVal) {
      self.log('prompt', [msg, defaultVal])
      return _prompt(msg, defaultVal)
    }

    // If we want to overload our console, then do it
    function getConsole (currentWindow) {
      return currentWindow.console || {
        log: function () {},
        info: function () {},
        warn: function () {},
        error: function () {},
        debug: function () {}
      }
    }
    if (self.config.captureConsole) {
      // patch the console
      var localConsole = contextWindow.console = getConsole(contextWindow)
      var logMethods = ['log', 'info', 'warn', 'error', 'debug']
      var patchConsoleMethod = function (method) {
        var orig = localConsole[method]
        if (!orig) {
          return
        }
        localConsole[method] = function () {
          self.log(method, arguments)
          try {
            return Function.prototype.apply.call(orig, localConsole, arguments)
          } catch (error) {
            self.log('warn', ['Console method ' + method + ' threw: ' + error])
          }
        }
      }
      for (var i = 0; i < logMethods.length; i++) {
        patchConsoleMethod(logMethods[i])
      }
    }
  }
}

// Define call/proxy methods
ContextKarma.getDirectCallParentKarmaMethod = function (parentWindow) {
  return function directCallParentKarmaMethod (method, args) {
    // If the method doesn't exist, then error out
    if (!parentWindow.karma[method]) {
      parentWindow.karma.error('Expected Karma method "' + method + '" to exist but it doesn\'t')
      return
    }

    // Otherwise, run our method
    parentWindow.karma[method].apply(parentWindow.karma, args)
  }
}
ContextKarma.getPostMessageCallParentKarmaMethod = function (parentWindow) {
  return function postMessageCallParentKarmaMethod (method, args) {
    parentWindow.postMessage({ __karmaMethod: method, __karmaArguments: args }, window.location.origin)
  }
}

// Export our module
module.exports = ContextKarma
