// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var test = require('prova');
var Promise = require('../../src/lib/promise');

var access = require('../../src/gen-vdl/v.io/v23/security/access');
var reserved = require('../../src/gen-vdl/v.io/v23/rpc/reserved');
var config = require('./default-config');
var MINUTE = 60 * 1000; // a minute
var Promise = require('../../src/lib/promise');
var random = require('../../src/lib/random');
var timeouts = require('./timeouts');
var vanadium = require('../../');
var verror = vanadium.verror;

var namespaceRoot = process.env.V23_NAMESPACE;
var PREFIX = 'namespace-testing/';

test('Test globbing children - glob(' + PREFIX + '*)', function(assert) {
  var runtime;

  init(config).then(function glob(rt) {
    runtime = rt;
    var namespace = rt.namespace();
    var ctx = runtime.getContext();
    var rpc = namespace.glob(ctx, PREFIX + '*');
    rpc.catch(end);
    return readAllNames(rpc.stream);
  }).then(function validate(actual) {
    var expected = [PREFIX + 'cottage', PREFIX + 'house'];
    assert.deepEqual(actual.sort(), expected.sort());
    end();
  }).catch(end);

  function end(err) {
    assert.error(err);
    if (runtime) {
      runtime.close(assert.end);
    } else {
      assert.end();
    }
  }
});

test('Test globbing nested levels - glob(' + PREFIX + 'cottage/*/*/*)',
  function(assert) {
    var runtime;

    init(config).then(function glob(rt) {
      runtime = rt;
      var namespace = rt.namespace();
      var ctx = runtime.getContext();
      var rpc = namespace.glob(ctx, PREFIX + 'cottage/*/*/*');
      rpc.catch(end);
      return readAllNames(rpc.stream);
    }).then(function validate(actual) {
      var expected = [
        PREFIX + 'cottage/lawn/back/sprinkler',
        PREFIX + 'cottage/lawn/front/sprinkler'
      ];
      assert.deepEqual(actual.sort(), expected.sort());
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test globbing non-existing name - glob(' + PREFIX + 'does/not/exist)',
  function(assert) {
    var runtime;

    init(config).then(function glob(rt) {
      runtime = rt;
      var namespace = rt.namespace();
      var ctx = runtime.getContext();
      var rpc = namespace.glob(ctx, PREFIX + 'does/not/exist');
      rpc.catch(end);
      return readAllNames(rpc.stream);
    }).then(function validate(actual) {
      var expected = [];
      assert.deepEqual(actual.sort(), expected.sort());
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test glob\'s promise is resolved when glob finishes.' +
  '- var promise = glob(' + PREFIX + '*)',
  function(assert) {
    var runtime;

    init(config).then(function glob(rt) {
      runtime = rt;
      var namespace = rt.namespace();
      var ctx = runtime.getContext();
      return namespace.glob(ctx, PREFIX + '*');
    }).then(function(finalResult) {
      assert.notOk(finalResult, 'there is no final result for glob');
      assert.pass('Promise resolved when glob finished.');
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test glob\'s callback is called when glob finishes.' +
  '- glob(' + PREFIX + '*, cb)',
  function(assert) {
    var runtime;

    init(config).then(function glob(rt) {
      runtime = rt;
      var namespace = rt.namespace();
      var ctx = runtime.getContext();
      namespace.glob(ctx, PREFIX + '*', function(err, finalResult) {
        assert.error(err);

        assert.notOk(finalResult, 'there is no final result for glob');
        assert.pass('Promise resolved when glob finished.');
        end();
      });
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test globbing non-existing rooted name - ' +
  'glob(/RootedBadName.Google.tld:1234/*)',
  function(assert) {

    // increase timeout for this test as it retries bad-url until timeout.
    assert.timeout(timeouts.long);

    var runtime;
    vanadium.init(config).then(function glob(rt) {
      runtime = rt;
      var namespace = rt.namespace();
      // Note: Glob will always timeout after 30s 
      // see v.io/x/ref/profiles/internal/naming/namespace/parallelstartcall.go
      // This means we'll get a timeout error on the glob stream before
      // timeouts.long expires.
      var rpc = namespace.glob(rt.getContext(),
        '/RootedBadName.Google.tld:1234/*');
      rpc.catch(function(err) {
        // Ignore the timeout error.
      });

      // We expect no actual result items but one stream error result item
      rpc.stream.on('data', function(item) {
        assert.notOk(item, 'Should not get any actual results');
      });

      var numErrorItems = 0;
      rpc.stream.on('error', function(errItem) {
        if (numErrorItems > 0) {
          end('expected only one error item');
        }
        numErrorItems++;
        assert.ok(errItem, 'Should get one error result item');
        assert.ok(errItem.error instanceof verror.TimeoutError,
          'error item should have error field of type TimeoutError');
        assert.equal(errItem.name, '/RootedBadName.Google.tld:1234',
          'error item should have a name');
      });

      rpc.stream.on('end', function() {
        assert.equal(numErrorItems, 1,
          'must end with 1 GlobError, got: ' + numErrorItems);
        end();
      });
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test mounting and unmounting - ' +
  'mount(' + PREFIX + 'new/name), unmount(' + PREFIX + 'new/name)',
  function(assert) {
    var runtime;
    var namespace;
    var expectedServerAddress;
    var initialName = PREFIX + 'first/name';
    var secondaryName = PREFIX + 'new/name';

    var ctx;
    var server;
    vanadium.init(config).then(function createServer(rt) {
        runtime = rt;
        namespace = rt.namespace();
        ctx = rt.getContext();
        server = rt.newServer();
        return server.serve(initialName, {});
      })
      .then(function() {
        return waitForPublish(initialName, runtime);
      })
      .then(function resolve() {
        return namespace.resolve(ctx, initialName);
      }).then(function mount(endpoints) {
        expectedServerAddress = endpoints[0];
        return namespace.mount(ctx, secondaryName, expectedServerAddress,
          MINUTE);
      }).then(function() {
        return waitForPublish(initialName, runtime);
      }).then(function resolve() {
        return namespace.resolve(ctx, secondaryName);
      }).then(function validate(resolveResult) {
        assert.equals(resolveResult.length, 1);
        assert.equals(resolveResult[0], expectedServerAddress);
      }).then(function unmount() {
        return namespace.unmount(ctx, secondaryName);
      }).then(function() {
        return waitForUnpublish(secondaryName, runtime);
      }).then(function resolve() {
        namespace.resolve(ctx, secondaryName, function cb(err) {
          assert.ok(err, 'no resolving after unmount()');
          end();
        });
      }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test resolving to mounttable - ' +
  'resolveToMountTable(' + PREFIX + 'cottage)',
  function(assert) {
    var runtime;

    var ctx;
    init(config).then(function resolveToMountTable(rt) {
      runtime = rt;
      ctx = runtime.getContext();
      var namespace = rt.namespace();
      return namespace.resolveToMounttable(ctx, PREFIX + 'cottage');
    }).then(function validate(mounttableNames) {
      assert.equals(mounttableNames.length, 1);
      var mounttableName = mounttableNames[0];
      assert.ok(mounttableName.indexOf(namespaceRoot) === 0);
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test flushing cache entry - ' +
  'flushCacheEntry(' + PREFIX + 'house/alarm)',
  function(assert) {
    var runtime;
    var namespace;
    var name = PREFIX + 'house/alarm';

    init(config).then(function flushCacheEntry(rt) {
      runtime = rt;
      namespace = rt.namespace();
      return namespace.flushCacheEntry(name);
    }).then(function validate() {
      // We don't check the return result of flushCachEntry since there is no
      // guarantee that it was in the cache to be flushed in the first place.
      // Even if we do a resolve() before this step to cache it, it may still
      // get evicted by the time we call flushCacheEntry for different reasons
      // such as cache being full, service remounting itself, parent mount-point
      // expiring.
      assert.pass('cache flushed');
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test disabling cache - disableCache(true)', function(assert) {
  var runtime;
  var namespace;
  var name = PREFIX + 'house/alarm';

  var ctx;
  init(config).then(function disableCache(rt) {
    runtime = rt;
    ctx = rt.getContext();
    namespace = rt.namespace();
    return namespace.disableCache(true);
  }).then(function resolveButItShouldNotGetCached(rt) {
    return namespace.resolve(ctx, name);
  }).then(function tryFlushCacheEntry() {
    return namespace.flushCacheEntry(name);
  }).then(function validate(flushed) {
    assert.notOk(flushed, 'no cache to be flushed');
    end();
  }).catch(end);

  function end(err) {
    assert.error(err);
    if (runtime) {
      runtime.close(assert.end);
    } else {
      assert.end();
    }
  }
});

test('Test setting roots to valid endpoints - ' +
  'setRoots(valid)',
  function(assert) {
    var runtime;
    var namespace;
    var ctx;

    init(config).then(function setRoots(rt) {
      runtime = rt;
      namespace = rt.namespace();
      ctx = rt.getContext();
      // Set the roots to a valid root, we expect normal glob results.
      return namespace.setRoots(namespaceRoot);
    }).then(function glob() {
      var rpc = namespace.glob(ctx, PREFIX + '*');
      rpc.catch(end);
      return readAllNames(rpc.stream);
    }).then(function validate(actual) {
      var expected = [PREFIX + 'cottage', PREFIX + 'house'];
      assert.deepEqual(actual.sort(), expected.sort());
      end();
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test setting roots to invalid endpoint - ' +
  'setRoots(invalid)',
  function(assert) {

    // increase timeout for this test as it retries bad-url until timeout.
    assert.timeout(timeouts.max);

    var runtime;
    var namespace;
    var ctx;
    vanadium.init(config).then(function setRoots(rt) {
      runtime = rt;
      namespace = rt.namespace();
      ctx = rt.getContext();
      // Set the roots to a invalid roots, then we don't expect resolution.
      return namespace.setRoots(['/bad-root-1.tld:80', '/bad-root-2.tld:1234']);
    }).then(function bind() {
      // Since setRoots changes runtimes Namespace roots, binding to any name
      // should now fail
      var client = runtime.newClient();
      ctx = ctx.withTimeout(timeouts.short);
      return client.bindTo(ctx, PREFIX + 'house/kitchen/lights')
        .then(function() {
          assert.fail('Should not have been able to bind with invalid roots');
        }, function(err) {
          assert.ok(err);
          assert.ok(err instanceof Error);
          ctx.finish();
          end();
        });
    }).catch(end);

    function end(err) {
      assert.error(err);
      if (runtime) {
        runtime.close(assert.end);
      } else {
        assert.end();
      }
    }
  });

test('Test getting roots - roots()', function(assert) {
  var runtime;

  init(config).then(function roots(rt) {
    runtime = rt;
    var namespace = rt.namespace();
    return namespace.roots();
  }).then(function validate(roots) {
    assert.equals(roots.length, 1);
    assert.ok(roots.indexOf(namespaceRoot === 0));
    end();
  }).catch(end);

  function end(err) {
    assert.error(err);
    if (runtime) {
      runtime.close(assert.end);
    } else {
      assert.end();
    }
  }
});

test('Test setting and getting roots - ' +
  'setRoots(), roots(cb)',
  function(assert) {
    var runtime;
    var namespace;

    vanadium.init(config, onInit);

    function onInit(err, rt) {
      assert.error(err);
      runtime = rt;
      namespace = rt.namespace();
      namespace.setRoots('/root1:80', '/root2:1234', onSetRoots);
    }

    function onSetRoots(err) {
      assert.error(err);
      namespace.roots(onRoots);
    }

    function onRoots(err, roots) {
      assert.error(err);
      assert.ok(roots[0].indexOf('root1:80' >= 0));
      assert.ok(roots[1].indexOf('root2:1234' >= 0));
      if (runtime) {
        runtime.close(assert.end);
      }
    }
  });

test('Test getPermissions() on non-existant name', function(assert) {
  vanadium.init(config, function(err, rt) {
    if (err) {
      return assert.end(err);
    }

    var ctx = rt.getContext();
    var ns = rt.namespace();
    var name = 'non/existant/name';

    ns.getPermissions(ctx, name, function(err) {
      assert.ok(err, 'should error');
      rt.close(assert.end);
    });
  });
});

test('Test setting and getting permissions - ' +
  'setPermissions(), getPermissions()',
  function(assert) {
    vanadium.init(config, function(err, rt) {
      if (err) {
        return assert.end(err);
      }

      var ctx = rt.getContext();
      var ns = rt.namespace();
      // Note: we use a random name here so we can run the test multiple times
      // with the same mounttable without getting locked out of a name.
      var name = 'path/to/some/name/' + random.hex();

      var perms = new access.Permissions(new Map([
        [access.Admin, new access.AccessList({
          'in': ['...'],
          'notIn': ['foo']
        })],
        [access.Read, new access.AccessList({
          'in': ['bar/baz']
        })],
        [access.Write, new access.AccessList({
          'notIn': ['biz/qux']
        })]
      ]));

      ns.setPermissions(ctx, name, perms, function(err) {
        if (err) {
          return end(err);
        }

        ns.getPermissions(ctx, name, function(err, gotPerms, gotVersion) {
          if (err) {
            return end(err);
          }

          assert.equal(typeof gotVersion, 'string',
            'getPermissions returns a string version');

          assert.ok(gotPerms, 'getPermissions returns a permissions');
          assert.deepEqual(gotPerms, perms.val,
            'getPermissions returns the same permissions that we set');

          ns.setPermissions(ctx, name, perms, 'wrongVersion', function(err) {
            assert.ok(err, 'setPermissions with a bad version should error');

            ns.setPermissions(ctx, name, perms, gotVersion, function(err) {
              assert.error(err,
                'setPermissions with the correct version should not error');
              end();
            });
          });
        });
      });

      function end(err) {
        assert.error(err, 'should not error');
        rt.close(assert.end);
      }
    });
  });

test('Test delete() on non-existant name', function(assert) {
  vanadium.init(config, function(err, rt) {
    if (err) {
      return assert.end(err);
    }

    var ctx = rt.getContext();
    var ns = rt.namespace();
    var name = 'non/existant/name';

    ns.delete(ctx, name, true, function(err) {
      assert.error(err, 'should not error');
      rt.close(assert.end);
    });
  });
});

test('Test delete() unmounts a name', function(assert) {

  vanadium.init(config, function(err, rt) {
    if (err) {
      return assert.end(err);
    }

    var ctx = rt.getContext();
    var ns = rt.namespace();
    var name = 'name/that/will/be/deleted';
    var ep = '/@3@ws@2.2.2.2:2222@e8972f90fe028674f78a164f001d07c5@5@7@s@@';

    ns.mount(ctx, name, ep, MINUTE)
      .then(function onMount(err) {
        if (err) {
          return end(err);
        }
      }).then(function() {
        return waitForPublish(name, rt);
      }).then(function resolveOnce() {
        return ns.resolve(ctx, name);
      }).then(function validateResolvedEp(gotEps) {
        assert.equal(gotEps.length, 1, 'resolves to a single endpoint');
        assert.equal(ep, gotEps[0], 'resolves to the correct endpoint');
      }).then(function deleteName() {
        return ns.delete(ctx, name, false);
      }).then(function resolveTwice() {
        ns.resolve(ctx, name, function(err) {
          assert.ok(err, 'name should be unmounted');
          end();
        });
      }).catch(function(err) {
        assert.error(err);
        end(err);
      });

    function end(err) {
      assert.error(err, 'should not error');
      rt.close(assert.end);
    }
  });
});

test('Test delete() on name with no children', function(assert) {
  vanadium.init(config, function(err, rt) {
    if (err) {
      return assert.end(err);
    }

    var ctx = rt.getContext();
    var ns = rt.namespace();
    var name = 'path/to/name/with/no/children';

    var perms = new access.Permissions(new Map([
      [access.Admin, new access.AccessList({
        'in': ['...'],
      })]
    ]));

    ns.setPermissions(ctx, name, perms, function(err) {
      if (err) {
        return end(err);
      }

      ns.delete(ctx, name, false, end);
    });

    function end(err) {
      assert.error(err, 'should not error');
      rt.close(assert.end);
    }
  });
});

test('Test delete() on name with children', function(assert) {
  vanadium.init(config, function(err, rt) {
    if (err) {
      return assert.end(err);
    }

    var ctx = rt.getContext();
    var ns = rt.namespace();
    var name = 'path/to/name/with/children';
    var childName1 = vanadium.naming.join(name, 'child1');
    var childName2 = vanadium.naming.join(name, 'node/child2');

    var perms = new access.Permissions(new Map([
      [access.Admin, new access.AccessList({
        'in': ['...'],
      })]
    ]));

    // Create all three names.
    ns.setPermissions(ctx, name, perms, function(err) {
      if (err) {
        return end(err);
      }
      ns.setPermissions(ctx, childName1, perms, function(err) {
        if (err) {
          return end(err);
        }
        ns.setPermissions(ctx, childName2, perms, function(err) {
          if (err) {
            return end(err);
          }

          ns.delete(ctx, name, false, function(err) {
            assert.ok(err, 'should error if we don\'t delete subchildren');

            ns.delete(ctx, name, true, function(err) {
              assert.error(err, 'should not error if we delete subchildren');
              end();
            });
          });
        });
      });
    });

    function end(err) {
      assert.error(err, 'should not error');
      rt.close(assert.end);
    }
  });
});

/*
 * Given a glob stream, returns a promise that will resolve to an array
 * of glob results after all the results have been collected from the stream.
 */
function readAllNames(stream) {
  var names = [];
  return new Promise(function(resolve, reject) {
    stream.on('data', function(mountPoint) {
      names.push(mountPoint.name);
    });

    stream.on('end', function(name) {
      resolve(names);
    });

    stream.on('error', function(errItem) {
      // we don't expect any errors other than GlobNotImplementedError
      if (!(errItem.error instanceof reserved.GlobNotImplementedError)) {
        reject(errItem.error);
      }
    });
  });
}

var SAMPLE_NAMESPACE = [
  'house/alarm',
  'house/living-room/lights',
  'house/living-room/smoke-detector',
  'house/kitchen/lights',
  'cottage/alarm',
  'cottage/lawn/back/sprinkler',
  'cottage/lawn/front/sprinkler',
];

function init(config) {
  var runtime;
  var server;
  return vanadium.init(config)
    .then(function serveEmptyService(rt) {
      runtime = rt;
      server = rt.newServer();
      return server.serve('', {});
    })
    .then(function publishUnderMultipleNames() {
      var addNamesRequests = SAMPLE_NAMESPACE.map(function(name) {
        return server.addName(PREFIX + name);
      });
      return Promise.all(addNamesRequests);
    })
    .then(function waitUntilAllNamesPublished() {
      var resolveRequests = SAMPLE_NAMESPACE.map(function(name) {
        return waitForPublish(PREFIX + name, runtime);
      });
      return Promise.all(resolveRequests);
    })
    .then(function ready() {
      return runtime;
    });

}

function waitForPublish(name, runtime) {
  return wait(name, runtime, false);
}

function waitForUnpublish(name, runtime) {
  return wait(name, runtime, true);
}

// Helper function that waits until name is published or unpublished,
// it checks every 100ms for a total of 50 tries before failing.
function wait(name, runtime, waitForUnpublish) {
  var WAIT_TIME = 100;
  var MAX_TRIES = 50;
  return new Promise(function(resolve, reject) {
    var ns = runtime.namespace();
    var count = 0;
    runResolve();

    function runResolve() {
      ns.resolve(runtime.getContext(), name, function(err, s) {
        if (err && err.id !== 'v.io/v23/naming.nameDoesntExist') {
          reject(err);
          return;
        }
        var continueLoop = err;
        if (waitForUnpublish) {
          continueLoop = !continueLoop;
        }
        if (continueLoop) {
          count++;
          if (count === MAX_TRIES) {
            var verb = waitForUnpublish ? 'unpublished' : 'published';
            reject(
              new Error('Timed out waiting for ' + name + ' to be ' + verb)
            );
            return;
          }
          return setTimeout(runResolve, WAIT_TIME);
        }
        resolve();
      });
    }
  });
}
