// Copyright (c) 2014, 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 'dart:io';

import 'package:async/async.dart';

import 'src/multi_headers.dart';
import 'src/utils.dart';

/// The error code for an error caused by a port already being in use.
final _addressInUseErrno = _computeAddressInUseErrno();
int _computeAddressInUseErrno() {
  if (Platform.isWindows) return 10048;
  if (Platform.isMacOS) return 48;
  assert(Platform.isLinux);
  return 98;
}

/// An implementation of `dart:io`'s [HttpServer] that wraps multiple servers
/// and forwards methods to all of them.
///
/// This is useful for serving the same application on multiple network
/// interfaces while still having a unified way of controlling the servers. In
/// particular, it supports serving on both the IPv4 and IPv6 loopback addresses
/// using [HttpMultiServer.loopback].
class HttpMultiServer extends StreamView<HttpRequest> implements HttpServer {
  /// The wrapped servers.
  final Set<HttpServer> _servers;

  /// Returns the default value of the `Server` header for all responses
  /// generated by each server.
  ///
  /// If the wrapped servers have different default values, it's not defined
  /// which value is returned.
  @override
  String? get serverHeader => _servers.first.serverHeader;

  @override
  set serverHeader(String? value) {
    for (var server in _servers) {
      server.serverHeader = value;
    }
  }

  /// Returns the default set of headers added to all response objects.
  ///
  /// If the wrapped servers have different default headers, it's not defined
  /// which header is returned for accessor methods.
  @override
  final HttpHeaders defaultResponseHeaders;

  @override
  Duration? get idleTimeout => _servers.first.idleTimeout;
  @override
  set idleTimeout(Duration? value) {
    for (var server in _servers) {
      server.idleTimeout = value;
    }
  }

  @override
  bool get autoCompress => _servers.first.autoCompress;
  @override
  set autoCompress(bool value) {
    for (var server in _servers) {
      server.autoCompress = value;
    }
  }

  /// Returns the port that one of the wrapped servers is listening on.
  ///
  /// If the wrapped servers are listening on different ports, it's not defined
  /// which port is returned.
  @override
  int get port => _servers.first.port;

  /// Returns the address that one of the wrapped servers is listening on.
  ///
  /// If the wrapped servers are listening on different addresses, it's not
  /// defined which address is returned.
  @override
  InternetAddress get address => _servers.first.address;

  @override
  set sessionTimeout(int value) {
    for (var server in _servers) {
      server.sessionTimeout = value;
    }
  }

  /// Creates an [HttpMultiServer] wrapping [servers].
  ///
  /// All [servers] should have the same configuration and none should be
  /// listened to when this is called.
  HttpMultiServer(Iterable<HttpServer> servers)
      : _servers = servers.toSet(),
        defaultResponseHeaders = MultiHeaders(
            servers.map((server) => server.defaultResponseHeaders)),
        super(StreamGroup.merge(servers));

  /// Creates an [HttpServer] listening on all available loopback addresses for
  /// this computer.
  ///
  /// See [HttpServer.bind].
  static Future<HttpServer> loopback(int port,
      {int backlog = 0, bool v6Only = false, bool shared = false}) {
    return _loopback(
        port,
        (address, port) => HttpServer.bind(address, port,
            backlog: backlog, v6Only: v6Only, shared: shared));
  }

  /// Like [loopback], but supports HTTPS requests.
  ///
  /// See [HttpServer.bindSecure].
  static Future<HttpServer> loopbackSecure(int port, SecurityContext context,
      {int backlog = 0,
      bool v6Only = false,
      bool requestClientCertificate = false,
      bool shared = false}) {
    return _loopback(
        port,
        (address, port) => HttpServer.bindSecure(address, port, context,
            backlog: backlog,
            v6Only: v6Only,
            shared: shared,
            requestClientCertificate: requestClientCertificate));
  }

  /// Bind an [HttpServer] with handling for special addresses 'localhost' and
  /// 'any'.
  ///
  /// For address 'localhost' behaves like [loopback].
  ///
  /// For 'any' listens on [InternetAddress.anyIPv6] if the system supports IPv6
  /// otherwise [InternetAddress.anyIPv4]. Note [InternetAddress.anyIPv6]
  /// listens on all hostnames for both IPv4 and IPv6.
  ///
  /// For any other address forwards directly to `HttpServer.bind` where
  /// the IPvX support may vary.
  ///
  /// See [HttpServer.bind].
  static Future<HttpServer> bind(dynamic address, int port,
      {int backlog = 0, bool v6Only = false, bool shared = false}) async {
    if (address == 'localhost') {
      return HttpMultiServer.loopback(port,
          backlog: backlog, v6Only: v6Only, shared: shared);
    }
    if (address == 'any') {
      return HttpServer.bind(
          await supportsIPv6
              ? InternetAddress.anyIPv6
              : InternetAddress.anyIPv4,
          port,
          backlog: backlog,
          v6Only: v6Only,
          shared: shared);
    }
    return HttpServer.bind(address, port,
        backlog: backlog, v6Only: v6Only, shared: shared);
  }

  /// Bind a secure [HttpServer] with handling for special addresses 'localhost'
  /// and 'any'.
  ///
  /// For address 'localhost' behaves like [loopback].
  ///
  /// For 'any' listens on [InternetAddress.anyIPv6] if the system supports IPv6
  /// otherwise [InternetAddress.anyIPv4]. Note [InternetAddress.anyIPv6]
  /// listens on all hostnames for both IPv4 and IPv6.
  ///
  /// See [HttpServer.bindSecure].
  static Future<HttpServer> bindSecure(
      dynamic address, int port, SecurityContext context,
      {int backlog = 0, bool v6Only = false, bool shared = false}) async {
    if (address == 'localhost') {
      return await HttpMultiServer.loopbackSecure(port, context,
          backlog: backlog, v6Only: v6Only, shared: shared);
    }
    if (address == 'any') {
      return await HttpServer.bindSecure(
          await supportsIPv6
              ? InternetAddress.anyIPv6
              : InternetAddress.anyIPv4,
          port,
          context,
          backlog: backlog,
          v6Only: v6Only,
          shared: shared);
    }
    return await HttpServer.bindSecure(address, port, context,
        backlog: backlog, v6Only: v6Only, shared: shared);
  }

  /// A helper method for initializing loopback servers.
  ///
  /// [bind] should forward to either [HttpServer.bind] or
  /// [HttpServer.bindSecure].
  static Future<HttpServer> _loopback(
      int port, Future<HttpServer> Function(InternetAddress, int port) bind,
      [int remainingRetries = 5]) async {
    if (!await supportsIPv4) {
      return await bind(InternetAddress.loopbackIPv6, port);
    }

    var v4Server = await bind(InternetAddress.loopbackIPv4, port);
    if (!await supportsIPv6) return v4Server;

    try {
      // Reuse the IPv4 server's port so that if [port] is 0, both servers use
      // the same ephemeral port.
      var v6Server = await bind(InternetAddress.loopbackIPv6, v4Server.port);
      return HttpMultiServer([v4Server, v6Server]);
    } on SocketException catch (error) {
      // If there is already a server listening we'll lose the reference on a
      // rethrow.
      await v4Server.close();

      if (error.osError?.errorCode != _addressInUseErrno) rethrow;
      if (port != 0) rethrow;
      if (remainingRetries == 0) rethrow;

      // A port being available on IPv4 doesn't necessarily mean that the same
      // port is available on IPv6. If it's not (which is rare in practice),
      // we try again until we find one that's available on both.
      return await _loopback(port, bind, remainingRetries - 1);
    }
  }

  @override
  Future close({bool force = false}) =>
      Future.wait(_servers.map((server) => server.close(force: force)));

  /// Returns an HttpConnectionsInfo object summarizing the total number of
  /// current connections handled by all the servers.
  @override
  HttpConnectionsInfo connectionsInfo() {
    var info = HttpConnectionsInfo();
    for (var server in _servers) {
      var subInfo = server.connectionsInfo();
      info.total += subInfo.total;
      info.active += subInfo.active;
      info.idle += subInfo.idle;
      info.closing += subInfo.closing;
    }
    return info;
  }
}
