// Copyright (c) 2013, 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.

// @dart = 2.9

import 'dart:async';
import 'dart:io';

import 'package:expect/expect.dart';

import 'test_utils.dart' show retry, throws;

Future testBindShared(String host, bool v6Only) async {
  final socket = await ServerSocket.bind(host, 0, v6Only: v6Only, shared: true);
  Expect.isTrue(socket.port > 0);

  final socket2 =
      await ServerSocket.bind(host, socket.port, v6Only: v6Only, shared: true);

  Expect.equals(socket.address.address, socket2.address.address);
  Expect.equals(socket.port, socket2.port);

  await socket.close();
  await socket2.close();
}

Future negTestBindSharedMismatch(String host, bool v6Only) async {
  final socket = await ServerSocket.bind(host, 0, v6Only: v6Only);
  Expect.isTrue(socket.port > 0);

  await throws(() => ServerSocket.bind(host, socket.port, v6Only: v6Only),
      (error) => error is SocketException && '$error'.contains('shared flag'));
  await socket.close();
}

Future negTestBindV6OnlyMismatch(String host, bool v6Only) async {
  final socket = await ServerSocket.bind(host, 0, v6Only: v6Only, shared: true);
  Expect.isTrue(socket.port > 0);

  await throws(
      () => ServerSocket.bind(host, socket.port, v6Only: !v6Only, shared: true),
      (error) => error is SocketException && '$error'.contains('v6Only flag'));

  await socket.close();
}

Future testBindDifferentAddresses(InternetAddress addr1, InternetAddress addr2,
    bool addr1V6Only, bool addr2V6Only) async {
  var socket =
      await ServerSocket.bind(addr1, 0, v6Only: addr1V6Only, shared: false);

  try {
    Expect.isTrue(socket.port > 0);

    var socket2 = await ServerSocket.bind(addr2, socket.port,
        v6Only: addr2V6Only, shared: false);
    try {
      Expect.equals(socket.port, socket2.port);
    } finally {
      await socket2.close();
    }
  } finally {
    await socket.close();
  }
}

Future testListenCloseListenClose(String host) async {
  ServerSocket socket = await ServerSocket.bind(host, 0, shared: true);
  ServerSocket socket2 =
      await ServerSocket.bind(host, socket.port, shared: true);

  var subscription = socket.listen((_) {
    throw 'error';
  });
  subscription.cancel();
  await socket.close();

  // The second socket should have kept the OS socket alive. We can therefore
  // test if it is working correctly.

  // For robustness we ignore any clients unrelated to this test.
  final receivedClientPorts = <int>[];
  socket2.listen((Socket client) async {
    receivedClientPorts.add(client.remotePort);
    await Future.wait([client.drain(), client.close()]);
  });

  final client = await Socket.connect(host, socket2.port);
  final clientPort = client.port;
  await client.close();
  await client.drain();

  Expect.isTrue(receivedClientPorts.contains(clientPort));

  // Close the second server socket.
  await socket2.close();
}

main() async {
  await retry(() async {
    await testBindDifferentAddresses(
        InternetAddress.anyIPv6, InternetAddress.anyIPv4, true, false);
  });
  await retry(() async {
    await testBindDifferentAddresses(
        InternetAddress.anyIPv4, InternetAddress.anyIPv6, false, true);
  });

  for (var host in ['127.0.0.1', '::1']) {
    await testBindShared(host, false);
    await testBindShared(host, true);

    await negTestBindSharedMismatch(host, false);
    await negTestBindSharedMismatch(host, true);

    await negTestBindV6OnlyMismatch(host, true);
    await negTestBindV6OnlyMismatch(host, false);

    await testListenCloseListenClose(host);
  }
}
