// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:async/async.dart';

import 'request.dart';
import 'handler.dart';
import 'server.dart';

/// A connected pair of a [Server] and a [Handler].
///
/// Requests to the handler are sent to the server's mounted handler once it's
/// available. This is used to expose a virtual [Server] that's actually one
/// part of a larger URL-space.
class ServerHandler {
  /// The server.
  ///
  /// Once this has a handler mounted, it's passed all requests to [handler]
  /// until this server is closed.
  Server get server => _server;
  final _HandlerServer _server;

  /// The handler.
  ///
  /// This passes requests to [server]'s handler. If that handler isn't mounted
  /// yet, the requests are handled once it is.
  Handler get handler => _onRequest;

  /// Creates a new connected pair of a [Server] with the given [url] and a
  /// [Handler].
  ///
  /// The caller is responsible for ensuring that requests to [url] or any URL
  /// beneath it are handled by [handler].
  ///
  /// If [onClose] is passed, it's called when [server] is closed. It may return
  /// a [Future] or `null`; its return value is returned by [Server.close].
  ServerHandler(Uri url, {onClose()})
      : _server = new _HandlerServer(url, onClose);

  /// Pipes requests to [server]'s handler.
  _onRequest(Request request) {
    if (_server._closeMemo.hasRun) {
      throw new StateError("Request received after the server was closed.");
    }

    if (_server._handler != null) return _server._handler(request);

    // Avoid async/await so that the common case of a handler already being
    // mounted doesn't involve any extra asynchronous delays.
    return _server._onMounted.then((_) => _server._handler(request));
  }
}

/// The [Server] returned by [ServerHandler].
class _HandlerServer implements Server {
  final Uri url;

  /// The callback to call when [close] is called, or `null`.
  final ZoneCallback _onClose;

  /// The mounted handler.
  ///
  /// This is `null` until [mount] is called.
  Handler _handler;

  /// A future that fires once [mount] has been called.
  Future get _onMounted => _onMountedCompleter.future;
  final _onMountedCompleter = new Completer();

  _HandlerServer(this.url, this._onClose);

  void mount(Handler handler) {
    if (_handler != null) {
      throw new StateError("Can't mount two handlers for the same server.");
    }

    _handler = handler;
    _onMountedCompleter.complete();
  }

  Future close() => _closeMemo.runOnce(() {
    return _onClose == null ? null : _onClose();
  });
  final _closeMemo = new AsyncMemoizer();
}
