// 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 readAllMountPoints(rpc.stream);
  }).then(function validate(actual) {
    var expected = [{
      name: PREFIX + 'cottage',
      isLeaf: false
    }, {
      name: PREFIX + 'house',
      isLeaf: false
    }];
    assertResults(actual, expected, assert);
    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 readAllMountPoints(rpc.stream);
    }).then(function validate(actual) {
      var expected = [{
        name: PREFIX + 'cottage/lawn/back/sprinkler',
        isLeaf: true
      }, {
        name: PREFIX + 'cottage/lawn/front/sprinkler',
        isLeaf: true
      }];
      assertResults(actual, expected, assert);
      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 readAllMountPoints(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 ||
          errItem.error instanceof verror.NoServersError,
          'error item should have error field of type TimeoutError or ' +
          'NoServersError');
        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 readAllMountPoints(rpc.stream);
    }).then(function validate(actual) {
      var expected = [{
        name: PREFIX + 'cottage',
        isLeaf: false
      }, {
        name: PREFIX + 'house',
        isLeaf: false
      }];
      assertResults(actual, expected, assert);
      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 = '/@5@ws@2.2.2.2:2222@e8972f90fe028674f78a164f001d07c5@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 readAllMountPoints(stream) {
  var mps = [];
  return new Promise(function(resolve, reject) {
    stream.on('data', function(mountPoint) {
      mps.push(mountPoint);
    });

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

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

function assertResults(got, want, assert) {
  var toEqual = [];
  got.forEach(function(e) {
    toEqual.push({
      name: e.name,
      isLeaf: e.isLeaf
    });
  });
  assert.deepEqual(want.sort(mpSorter), toEqual.sort(mpSorter));

  function mpSorter(a, b) {
    return a.name.localeCompare(b.name);
  }
}

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();
      });
    }
  });
}