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

class ChildServerProcess {
  /// [IOSink]s like [stdout] don't like to be piped more than one [Stream], but
  /// we want to pipe many of them (basically, every standard output and error
  /// of every child process we open), so we pipe to an accommodating consumer.
  static final _consoleOut = new _MultipleStreamConsumer(stdout);

  final Process process;
  final String host;
  final int port;
  ChildServerProcess._(this.process, this.host, this.port);

  get httpUri => Uri.parse('http://$host:$port');

  static build(Future<Process> builder(String host, int port),
      {int defaultPort: 1024,
      int maxPort: 65535,
      String host: '0.0.0.0'}) async {
    var port = await _findUnusedPort(defaultPort, maxPort);
    var p = (await builder(host, port))
      ..stdout.pipe(_consoleOut)
      ..stderr.pipe(_consoleOut);
    await _waitForServer(host, port);
    return new ChildServerProcess._(p, host, port);
  }

  static _waitForServer(String host, int port,
      {int attempts: 10,
      Duration retryDelay: const Duration(seconds: 1)}) async {
    var lastError;
    for (int i = 0; i < attempts; i++) {
      try {
        await (await Socket.connect(host, port)).close();
        return;
      } catch (e) {
        lastError = e;
        await new Future.delayed(retryDelay);
      }
    }
    throw new StateError(
        'Failed to connect to $host:$port after $attempts attempts; '
        'Last error:\n$lastError');
  }

  static Future<int> _findUnusedPort(int fromPort, int toPort) async {
    var lastError;
    for (int port = fromPort; port <= toPort; port++) {
      try {
        await (await ServerSocket.bind(InternetAddress.ANY_IP_V4, port))
            .close();
        return port;
      } catch (e) {
        lastError = e;
      }
    }
    throw new StateError(
        'Failed to find an unused port between $fromPort and $toPort; '
        'Last error:\n$lastError');
  }
}

/// A consumer into which we can pipe as many streams as we want, that forwards
/// everything to an [IOSink] (such as [stdout]).
class _MultipleStreamConsumer extends StreamConsumer<List<int>> {
  final IOSink _sink;
  _MultipleStreamConsumer(this._sink);

  @override
  Future addStream(Stream<List<int>> stream) async {
    await for (var data in stream) {
      _sink.add(data);
    }
  }

  @override
  close() {}
}
