// 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 vanadium = require('../../');
var config = require('./default-config');
var extend = require('xtend');
var defaults = {
  autoBind: true
};

module.exports = serve;

// # serve(name, dispatcher, callback)
//
// DRYs up test code by wrapping the default success case for:
//
//    vanadium.init() ->
//    runtime.server(name, dispatcher, ...) ->
//    runtime.bindTo(ctx, name, ...) -> r
//    assertions ->
//    runtime.close()
//
// To make a connection to the default integration test wspr instance and
// bind to a service use:
//
//     serve('test/service', dispatcher, function(err, res) {
//       res.service.returnBuiltInError(function(err) {
//         assert.error(err)
//
//         // your assertions here...
//
//         // `res` has several attributes to make your life easier:
//         //
//         // * runtime: vanadium runtime object
//         // * config: config passed into vanadium.init()
//         // * server: returned from runtime._getServer()
//         // * service: returned from runtime.bindTo(name, ...)
//         // * end: the end function to shut down the connection
//
//
//         // use the `res.end` function to close the underlying runtime/wspr
//         // connection and end your test run.
//         res.end(assert);
//       })
//     })
//
function serve(name, dispatcher, callback) {
  var options = defaults;
  var serverOption;
  // alternate: serve(options, callback)
  if (typeof name === 'object') {
    options = extend(defaults, name);
    callback = dispatcher;
    name = options.name;
    dispatcher = options.dispatcher;
    serverOption = options.serverOption;
  }

  vanadium.init(config, function(err, runtime) {
    // basic response used for failures where we want .close and .end to
    // still work:
    var basicRes = {
      end: end,
      close: close
    };

    if (err) {
      return callback(err, basicRes);
    }

    runtime.newDispatchingServer(name, dispatcher, serverOption,
      function(err, server) {

        if (err) {
          return callback(err, basicRes);
        }

        var ctx = runtime.getContext();

        waitUntilResolve();

        // The server is not gauranteed to be mounted by the time the
        // serve call finishes.  We should wait until the name
        // resolves before calling the callback.  As a side a benefit,
        // this also speeds up the browser tests, because browspr is
        // quicker than wspr and so it is more likely to return before
        // the server is mounted.  The normal backoff for bindTo
        // starts at 100ms, but this code only waits a few
        // milliseconds.  TODO(mattr): I have temporarily set this to
        // retry at longer intervals. In practice this previous code
        // (which checked every 10ms) allowed the server up to 0.5s or
        // so to mount through the proxy.  In the new RPC system it
        // can take a bit longer.  I upped the number of attempts and
        // retry time to compensate.  We will eventually optimize this
        // time back down.
        function waitUntilResolve() {
          var ns = runtime.getNamespace();
          var count = 0;
          runResolve();

          function runResolve() {
            ns.resolve(ctx, name, function(err, s) {
              if (err || s.length === 0) {
                count++;
                if (count === 20) {
                  return callback(
                    new Error(
                      'Timed out waiting for resolve in serve.js: ' + err),
                    basicRes);
                }
                return setTimeout(runResolve, 100);
              }
              completeServe();
            });
          }
        }

        function completeServe() {
          var res = {
            runtime: runtime,
            config: config,
            close: close,
            end: end,
            server: server
          };

          if (options.autoBind === false) {
            return callback(err, res, end);
          }

          function onBind(err, service) {
            if (err) {
              return callback(err, basicRes);
            }

            res.service = service;
            callback(err, res, end);
          }
          var client = runtime.getClient();
          client.bindTo(ctx, name, onBind);
        }
      });

    function close(callback) {
      return runtime.close(callback);
    }

    // hoisted and passed as the last argument to the callback argument.
    function end(assert, errorMsg) {
      if (!!assert.end && typeof assert.end === 'function') {
        return close(function(err) {
          assert.error(err, 'should not error on runtime.close(...)');
          assert.end(errorMsg);
        });
      } else {
        var message = 'end(callback) requires an assert object';
        throw new Error(message);
      }
    }
  });
}
