// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.


// Simple tests of most basic domain functionality.

var common = require('../common');
var assert = require('assert');
var domain = require('domain');
var events = require('events');
var fs = require('fs');
var caught = 0;
var expectCaught = 0;

var d = new domain.Domain();
var e = new events.EventEmitter();

d.on('error', function(er) {
  console.error('caught', er && (er.message || er));

  var er_message = er.message;
  var er_path = er.path

  // On windows, error messages can contain full path names. If this is the
  // case, remove the directory part.
  if (typeof er_path === 'string') {
    var slash = er_path.lastIndexOf('\\');
    if (slash !== -1) {
      var dir = er_path.slice(0, slash + 1);
      er_path = er_path.replace(dir, '');
      er_message = er_message.replace(dir, '');
    }
  }

  switch (er_message) {
    case 'emitted':
      assert.equal(er.domain, d);
      assert.equal(er.domainEmitter, e);
      assert.equal(er.domainThrown, false);
      break;

    case 'bound':
      assert.ok(!er.domainEmitter);
      assert.equal(er.domain, d);
      assert.equal(er.domainBound, fn);
      assert.equal(er.domainThrown, false);
      break;

    case 'thrown':
      assert.ok(!er.domainEmitter);
      assert.equal(er.domain, d);
      assert.equal(er.domainThrown, true);
      break;

    case "ENOENT, open 'this file does not exist'":
      assert.equal(er.domain, d);
      assert.equal(er.domainThrown, false);
      assert.equal(typeof er.domainBound, 'function');
      assert.ok(!er.domainEmitter);
      assert.equal(er.code, 'ENOENT');
      assert.equal(er_path, 'this file does not exist');
      assert.equal(typeof er.errno, 'number');
      break;

    case "ENOENT, open 'stream for nonexistent file'":
      assert.equal(typeof er.errno, 'number');
      assert.equal(er.code, 'ENOENT');
      assert.equal(er_path, 'stream for nonexistent file');
      assert.equal(er.domain, d);
      assert.equal(er.domainEmitter, fst);
      assert.ok(!er.domainBound);
      assert.equal(er.domainThrown, false);
      break;

    case 'implicit':
      assert.equal(er.domainEmitter, implicit);
      assert.equal(er.domain, d);
      assert.equal(er.domainThrown, false);
      assert.ok(!er.domainBound);
      break;

    case 'implicit timer':
      assert.equal(er.domain, d);
      assert.equal(er.domainThrown, true);
      assert.ok(!er.domainEmitter);
      assert.ok(!er.domainBound);
      break;

    case 'Cannot call method \'isDirectory\' of undefined':
      assert.equal(er.domain, d);
      assert.ok(!er.domainEmitter);
      assert.ok(!er.domainBound);
      break;

    case 'nextTick execution loop':
      assert.equal(er.domain, d);
      assert.ok(!er.domainEmitter);
      assert.ok(!er.domainBound);
      break;

    default:
      console.error('unexpected error, throwing %j', er.message, er);
      throw er;
  }

  caught++;
});



process.on('exit', function() {
  console.error('exit', caught, expectCaught);
  assert.equal(caught, expectCaught, 'caught the expected number of errors');
  console.log('ok');
});



// revert to using the domain when a callback is passed to nextTick in
// the middle of a tickCallback loop
d.run(function() {
  process.nextTick(function() {
    throw new Error('nextTick execution loop');
  });
});
expectCaught++;



// catch thrown errors no matter how many times we enter the event loop
// this only uses implicit binding, except for the first function
// passed to d.run().  The rest are implicitly bound by virtue of being
// set up while in the scope of the d domain.
d.run(function() {
  process.nextTick(function() {
    var i = setInterval(function () {
      clearInterval(i);
      setTimeout(function() {
        fs.stat('this file does not exist', function(er, stat) {
          // uh oh!  stat isn't set!
          // pretty common error.
          console.log(stat.isDirectory());
        });
      });
    });
  });
});
expectCaught++;



// implicit addition of a timer created within a domain-bound context.
d.run(function() {
  setTimeout(function() {
    throw new Error('implicit timer');
  });
});
expectCaught++;



// Event emitters added to the domain have their errors routed.
d.add(e);
e.emit('error', new Error('emitted'));
expectCaught++;



// get rid of the `if (er) return cb(er)` malarky, by intercepting
// the cb functions to the domain, and using the intercepted function
// as a callback instead.
function fn(er) {
  throw new Error('This function should never be called!');
  process.exit(1);
}

var bound = d.intercept(fn);
bound(new Error('bound'));
expectCaught++;



// intercepted should never pass first argument to callback
function fn2(data) {
  assert.equal(data, 'data', 'should not be null err argument')
}

var bound = d.intercept(fn2);
bound(null, 'data');

// intercepted should never pass first argument to callback
// even if arguments length is more than 2.
function fn3(data, data2) {
  assert.equal(data, 'data', 'should not be null err argument');
  assert.equal(data2, 'data2', 'should not be data argument');
}

bound = d.intercept(fn3);
bound(null, 'data', 'data2');

// throwing in a bound fn is also caught,
// even if it's asynchronous, by hitting the
// global uncaughtException handler. This doesn't
// require interception, since throws are always
// caught by the domain.
function thrower() {
  throw new Error('thrown');
}
setTimeout(d.bind(thrower), 100);
expectCaught++;



// Pass an intercepted function to an fs operation that fails.
fs.open('this file does not exist', 'r', d.intercept(function(er) {
  console.error('should not get here!', er);
  throw new Error('should not get here!');
}, true));
expectCaught++;



// implicit addition by being created within a domain-bound context.
var implicit;

d.run(function() {
  implicit = new events.EventEmitter;
});

setTimeout(function() {
  // escape from the domain, but implicit is still bound to it.
  implicit.emit('error', new Error('implicit'));
}, 10);
expectCaught++;


var result = d.run(function () {
  return 'return value';
});
assert.equal(result, 'return value');


var fst = fs.createReadStream('stream for nonexistent file')
d.add(fst)
expectCaught++;
