var test = require('prova');
var mercury = require('mercury');
var _ = require('lodash');
var proxyquire = require('proxyquireify')(require);
var mockLRUCache = require('./mocks/lru-cache');

// @noCallThru ensures this completely overrdies the original config
// instead of inheriting the properties that are not defined here from
// the original dependency
var veyronConfigForTest = {
  '@noCallThru': true
};

// The NAMESPACE_ROOT environment variable is set by servicerunner in the "make
// test" target.  That environment variable is picked up by the "envify" prova
// transform and used to set process.env.NAMESPACE_ROOT.
var globalRoot = process.env.NAMESPACE_ROOT;

// Require namespaceService but using test specific mocks and configs
var namespaceService =
  proxyquire('../../../../src/services/namespace/service.js', {
    '../../veyron-config': veyronConfigForTest,
    'lru-cache': function() {
      return mockLRUCache;
    }
  });

test('getChildren of default namespace root', function(t) {
  namespaceService.getChildren().
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 top level items: cottage, house
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        assertCottage(children[0]);
        assertHouse(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertCottage(item) {
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
  }

  function assertHouse(item) {
    assertServer(t, item, {
      name: 'house',
      objectName: 'house',
      isGlobbable: true,
      type: 'mounttable'
    });
  }
});

test('getChildren of cottage/lawn', function(t) {
  namespaceService.getChildren('cottage/lawn').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 3 items back, front and master-sprinkler
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        assertBack(children[0]);
        assertSprinkler(children[2]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertSprinkler(item) {
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertBack(item) {
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
  }
});

test('getChildren of rooted ' + globalRoot + '/house/kitchen', function(t) {
  namespaceService.getChildren(globalRoot + '/house/kitchen').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 items, lights and smoke-detector
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: globalRoot + '/house/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: globalRoot + '/house/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

// The HOUSE_MOUNTTABLE environment variable is set by run-tests.sh.  That
// environment variable is picked up by the "envify" prova transform and used to
// set process.env.HOUSE_MOUNTTABLE.
var hostPortRoot = process.env.HOUSE_MOUNTTABLE;

test('getChildren of rooted ' + hostPortRoot + '/kitchen', function(t) {
  namespaceService.getChildren(hostPortRoot + '/kitchen').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 items, lights and smoke-detector
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: hostPortRoot + '/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: hostPortRoot + '/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

test('getChildren of non-existing mounttable', function(t) {
  // TODO(aghassemi) why does namespace library return empty results instead of
  // error when globbing rooted names that don't exist?
  namespaceService.getChildren('/DoesNotExist:666/What/Ever').
  then(function assertResult(result) {
    result.events.on('end', function validate() {
      // Expect empty results
      mercury.watch(result, function(children) {
        t.deepEqual(children, []);
        t.end();
      });
    });
    result.events.on('streamError', function(error) {
      // we do actually expect an error in this case
      t.ok(error);
    });
    result.events.on('itemError', t.end);
  }).catch(t.end);
});

test('getNamespaceItem of leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/master-sprinkler').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of intermediary name', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/back').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of mounttable leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
    t.end();
  }).catch(t.end);
});

test('search uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.search('house', '*').
  then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/*'),
      'first glob call is not a cache hit');

    // Call second time, there should have been a cache hit
    return namespaceService.search('house', '*');
  }).then(function assertCacheHit() {
    t.ok(mockLRUCache.wasCacheHit('glob|house/*'),
      'second glob call is a cache hit');

    // Call glob with same name, different query
    return namespaceService.search('house', 'foo*');
  }).then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/foo*'),
      'third glob call with different query is not a cache hit');
    t.end();
  }).catch(t.end);
});

test('getSignature uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.getSignature('house/alarm').then(function() {
    t.notOk(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'first getSignature call is not a cache hit');
    // Call a second time
    return namespaceService.getSignature('house/alarm');
  }).then(function() {
    t.ok(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'second getSignature call is a cache hit');
    // Call a different name
    return namespaceService.getSignature('house/kitchen/smoke-detector');
  }).then(function() {
    t.notOk(mockLRUCache.wasCacheHit(
      'getSignature|house/kitchen/smoke-detector'
    ),'third getSignature call to a different name is not a cache hit');
    t.end();
  }).catch(t.end);
});

//TODO(aghassemi)
//Tests for:
// Recursive glob
// Glob with some keyword
// Ensuring array is updated when nodes get mounted and unmounted (when we use
// watchGlob)

// Make RPC: good inputs => no error
var okRPCs = {
  'no input':     ['house/alarm', 'status', []],
  'bool input':   ['house/living-room/lights', 'flipSwitch', [true]],
  'int input':    ['cottage/smoke-detector', 'sensitivity', [2]],
  'float input':  ['house/alarm', 'delayArm', [2.5]],
  'string input': ['cottage/pool/speaker', 'playSong', ['Happy Birthday']],
  'slice input':  ['house/master-bedroom/speaker', 'addSongs', [['A', 'B']]],
  '2+ inputs':    ['cottage/pool/heater', 'start', [70, 5]],
};

_.forOwn(okRPCs, function run(params, inputType) {
  test(
    'makeRPC accepts good input - ' + inputType,
    testMakeRPCNoError.bind(null, params)
  );
});

// Make RPC: bad inputs => error
var badRPCs = {
  //TODO(aghassemi) re-enable after #483
  //'no service':    ['mansion/smoke-detector', 'status', []],
  'no method':     ['cottage/pool/speaker', 'status', []],
  'no input':      ['cottage/lights','flipSwitch', null],
  'bad type':      ['cottage/lights','flipSwitch', ['notBool']],
  'lacks input':   ['cottage/pool/heater','start', [80]],
  'invalid input': ['house/living-room/blast-speaker','playSong', ['notThere']]
};

_.forOwn(badRPCs, function run(params, inputType) {
  test(
    'makeRPC errors on bad input - ' + inputType,
    testMakeRPCHasError.bind(null, params)
  );
});

// Make RPC: outputs have the expected # of outputs
test('makeRPC returns output properly', function(t) {
  namespaceService.makeRPC('cottage/alarm', 'panic', []).then(
    function got0Outputs(res) { // 0 outputs: has no result.
      t.ok(res === undefined, '0 outputs => is undefined');

      return namespaceService.makeRPC('house/alarm', 'status', []);
    }
  ).then( // 1 output: (Non-array/slice output) is not an Array.
    function got1Output(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/smoke-detector', 'test', []);
    }
  ).then( // 1 output: Delayed return. Also not an array.
    function got1OutputDelayed(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/pool/heater', 'status', []);
    }
  ).then( // 2 outputs: Is an Array of the correct length.
    function got2Outputs(res) {
      var ok = res instanceof Array && res.length === 2;
      t.ok(ok, '2 outputs => length 2 Array');
      t.end();
    }
  ).catch(t.end);
});

/*
 * Test helpers
 */
function assertServer(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsServer(t, item);
  if (vals.isGlobbable === true) {
    assertIsGlobbable(t, item);
  } else if(vals.isGlobbable === false) {
    assertIsNotGlobbable(t, item);
  }

  if (vals.type === 'unknown') {
    assertUnknownServiceTypeInfo(t, item);
  } else if (vals.type === 'mounttable') {
    assertMounttableServiceTypeInfo(t, item);
  } else {
    t.fail('Unknown type: ' + vals.type);
  }
}

function assertIntermediaryName(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsNotServer(t, item);
  assertIsGlobbable(t, item);
}

function assertMountedName(t, item, val) {
  t.ok(item.mountedName, item.mountedName + ': has a mounted name');
  t.equal(item.mountedName, val, item.mountedName + ': mounted name matches');
}

function assertObjectName(t, item, val) {
  t.ok(item.objectName, item.mountedName + ': has an object name');
  t.equal(item.objectName, val, item.mountedName + ': object name matches');
}

function assertIsServer(t, item) {
  t.equal(item.isServer, true, item.mountedName + ': is a server');
  t.ok(item.serverInfo, item.mountedName + ': has server info');
  t.ok(item.serverInfo.endpoints.length > 0, item.mountedName +
    ': has at least 1 endpoint');
}

function assertIsNotServer(t, item) {
  t.equal(item.isServer, false, item.mountedName + ': is not a server');
}

function assertIsGlobbable(t, item) {
  t.equal(item.isGlobbable, true, item.mountedName + ': is globbable');
}

function assertIsNotGlobbable(t, item) {
  t.equal(item.isGlobbable, false, item.mountedName + ': is not globbable');
}

function assertIsImmutable(t, observable) {
  t.ok(observable.set === undefined, 'is immutable');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of Unknown Service.
 */
function assertUnknownServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-unknown',
    item.mountedName + ': unknown type info has the right key');

  t.equal(typeInfo.typeName, 'Service',
    item.mountedName + ': unknown type info has the type name');

  t.equal(typeInfo.description, null,
    item.mountedName + ': unknown type info does not have description');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of mounttable.
 */
function assertMounttableServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-mounttable',
    item.mountedName + ': mounttable type info has the right key');

  t.equal(typeInfo.typeName, 'Mount Table',
    item.mountedName + ': mounttable type info has the type name');

  t.ok(typeInfo.description,
    item.mountedName + ': mounttable type info has a description');
}
/*
 * Runs a test to ensure the makeRPC call terminates without error.
 */
function testMakeRPCNoError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.pass('completed without error');
    t.end();
  }).catch(function(err) {
    t.end(err);
  });
}

/*
 * Runs a test to ensure the makeRPC call terminates with an error.
 */
function testMakeRPCHasError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.fail('should not have completed without error');
    t.end();
  }).catch(function(err) {
    t.pass('correctly returned an error');
    t.end();
  });
}
