// 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:io';
import 'dart:async';

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
import "test_utils.dart" show retry;

const ANY = InternetAddressType.any;

Future testIPv6toIPv6() {
  asyncStart();
  return InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
    return InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
      return ServerSocket.bind(serverAddr.first, 0).then((server) {
        Expect.equals('::0', server.address.host);
        Expect.equals('::', server.address.address);
        server.listen((socket) {
          socket.destroy();
          server.close();
          asyncEnd();
        });
        return Socket.connect(clientAddr.first, server.port).then((socket) {
          socket.destroy();
        });
      });
    });
  });
}

Future testIPv4toIPv6() {
  asyncStart();
  return InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
    return ServerSocket.bind(serverAddr.first, 0).then((server) {
      Expect.equals('::0', server.address.host);
      Expect.equals('::', server.address.address);
      server.listen((socket) {
        socket.destroy();
        server.close();
        asyncEnd();
      });
      return Socket.connect("127.0.0.1", server.port).then((socket) {
        socket.destroy();
      });
    });
  });
}

Future testIPv6toIPv4() {
  asyncStart();
  return InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
    return ServerSocket.bind("127.0.0.1", 0).then((server) {
      Expect.equals('127.0.0.1', server.address.host);
      Expect.equals('127.0.0.1', server.address.address);
      server.listen((socket) {
        throw "Unexpected socket";
      });
      return Socket.connect(clientAddr.first, server.port).then((socket) {
        socket.destroy();
        throw "Unexpected connect";
      }, onError: (e) {}).whenComplete(() {
        server.close();
        asyncEnd();
      });
    });
  });
}

Future testIPv4toIPv4() {
  asyncStart();
  return ServerSocket.bind("127.0.0.1", 0).then((server) {
    Expect.equals('127.0.0.1', server.address.host);
    Expect.equals('127.0.0.1', server.address.address);
    server.listen((socket) {
      socket.destroy();
      server.close();
      asyncEnd();
    });
    return Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.destroy();
    });
  });
}

Future testIPv6Lookup() {
  asyncStart();
  return InternetAddress.lookup("::0", type: ANY).then((list) {
    if (list.length < 0) throw "no address";
    for (var entry in list) {
      if (entry.type != InternetAddressType.IPv6) {
        throw "Wrong IP type";
      }
    }
    asyncEnd();
  });
}

Future testIPv4Lookup() {
  asyncStart();
  return InternetAddress.lookup("127.0.0.1").then((list) {
    if (list.length < 0) throw "no address";
    for (var entry in list) {
      if (entry.type != InternetAddressType.IPv4) {
        throw "Wrong IP type";
      }
    }
    asyncEnd();
  });
}

Future testIPv4toIPv6_IPV6Only() {
  asyncStart();
  return InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
    return ServerSocket.bind(serverAddr.first, 0, v6Only: true).then((server) {
      server.listen((socket) {
        throw "Unexpected socket";
      });
      return Socket.connect("127.0.0.1", server.port).then((socket) {
        socket.destroy();
        throw "Unexpected connect";
      }, onError: (e) {}).whenComplete(() {
        server.close();
        asyncEnd();
      });
    });
  });
}

main() async {
  asyncStart();
  await testIPv6toIPv6(); //               //# 01: ok
  await testIPv4toIPv6(); //               //# 02: ok
  await testIPv4toIPv4(); //               //# 03: ok
  await testIPv6Lookup(); //               //# 04: ok
  await testIPv4Lookup(); //               //# 05: ok

  await retry(testIPv6toIPv4); //          //# 06: ok
  await retry(testIPv4toIPv6_IPV6Only); // //# 07: ok
  asyncEnd();
}
