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

import 'package:expect/expect.dart';

import 'test_utils.dart' show withTempDir;

Future testAddress(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  var server = await ServerSocket.bind(address, 0);

  var client = await Socket.connect(address, server.port);
  var completer = Completer<void>();
  server.listen((socket) async {
    Expect.equals(socket.port, 0);
    Expect.equals(socket.port, server.port);
    Expect.equals(client.port, socket.remotePort);
    Expect.equals(client.remotePort, socket.port);

    // Client has not bound to a path. This is an unnamed socket.
    Expect.equals(socket.remoteAddress.toString(), "InternetAddress('', Unix)");
    Expect.equals(client.remoteAddress.toString(), address.toString());
    socket.destroy();
    client.destroy();
    await server.close();
    completer.complete();
  });
  await completer.future;
}

testBindShared(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  var socket = await ServerSocket.bind(address, 0, shared: true);
  Expect.isTrue(socket.port == 0);

  // Same path
  var socket2 = await ServerSocket.bind(address, 0, shared: true);
  Expect.equals(socket.address.address, socket2.address.address);
  Expect.equals(socket.port, socket2.port);

  // Test relative path
  var path = name.substring(name.lastIndexOf('/') + 1);
  address = InternetAddress('${name}/../${path}/sock',
      type: InternetAddressType.unix);

  var socket3 = await ServerSocket.bind(address, 0, shared: true);
  Expect.isTrue(FileSystemEntity.identicalSync(
      socket.address.address, socket3.address.address));
  Expect.equals(socket.port, socket2.port);
  await socket.close();
  await socket2.close();
  await socket3.close();
}

testBind(String name) async {
  final address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  final server = await ServerSocket.bind(address, 0, shared: false);
  Expect.isTrue(server.address.toString().contains(name));
  // Unix domain socket does not have a valid port number.
  Expect.equals(server.port, 0);

  final serverContinue = Completer();
  final clientContinue = Completer();
  server.listen((s) async {
    await serverContinue.future;
    clientContinue.complete();
  });

  final socket = await Socket.connect(address, server.port);
  socket.write(" socket content");
  serverContinue.complete();
  await clientContinue.future;

  socket.destroy();
  await server.close();
}

Future testListenCloseListenClose(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  ServerSocket socket = await ServerSocket.bind(address, 0, shared: true);
  ServerSocket socket2 =
      await ServerSocket.bind(address, socket.port, shared: true);

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

  // For robustness we ignore any clients unrelated to this test.
  List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  socket2.listen((Socket client) async {
    client.add(sendData);
    await Future.wait([client.drain(), client.close()]);
  });

  final client = await Socket.connect(address, socket2.port);
  List<int> data = [];
  var completer = Completer<void>();
  client.listen(data.addAll, onDone: () {
    Expect.listEquals(sendData, data);
    completer.complete();
  });
  await completer.future;
  await client.close();

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

Future testSourceAddressConnect(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  ServerSocket server = await ServerSocket.bind(address, 0);

  var completer = Completer<void>();
  var localAddress =
      InternetAddress('$name/local', type: InternetAddressType.unix);
  server.listen((Socket socket) async {
    Expect.equals(socket.address.address, address.address);
    Expect.equals(socket.remoteAddress.address, localAddress.address);
    socket.drain();
    socket.close();
    completer.complete();
  });

  Socket client =
      await Socket.connect(address, server.port, sourceAddress: localAddress);
  Expect.equals(client.remoteAddress.address, address.address);
  await completer.future;
  await client.close();
  await client.drain();
  await server.close();
}

Future testAbstractAddress(String uniqueName) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }
  var serverAddress =
      InternetAddress('@temp.sock.$uniqueName', type: InternetAddressType.unix);
  ServerSocket server = await ServerSocket.bind(serverAddress, 0);
  final completer = Completer<void>();
  final content = 'random string';
  server.listen((Socket socket) {
    socket.listen((data) {
      Expect.equals(content, utf8.decode(data));
      socket.close();
      server.close();
      completer.complete();
    });
  });

  Socket client = await Socket.connect(serverAddress, 0);
  client.write(content);
  await client.drain();
  await client.close();
  await completer.future;
}

String getAbstractSocketTestFileName() {
  var executable = Platform.executable;
  var dirIndex = executable.lastIndexOf('dart');
  var buffer = new StringBuffer(executable.substring(0, dirIndex));
  buffer.write('abstract_socket_test');
  return buffer.toString();
}

Future testShortAbstractAddress(String uniqueName) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }
  var retries = 10;
  var retryDelay = const Duration(seconds: 1);
  Process? process;
  Future? stdoutFuture;
  Future? stderrFuture;
  try {
    var socketAddress = '@temp.sock.$uniqueName';
    var abstractSocketServer = getAbstractSocketTestFileName();
    // check if the executable exists, some build configurations do not
    // build it (e.g: precompiled simarm/simarm64)
    if (!File(abstractSocketServer).existsSync()) {
      return;
    }

    // Start up a subprocess that listens on [socketAddress].
    process = await Process.start(abstractSocketServer, [socketAddress]);
    stdoutFuture = process.stdout
        .transform(const Utf8Decoder(allowMalformed: true))
        .listen(stdout.write)
        .asFuture(null);
    stderrFuture = process.stderr
        .transform(const Utf8Decoder(allowMalformed: true))
        .listen(stderr.write)
        .asFuture(null);
    var serverAddress =
        InternetAddress(socketAddress, type: InternetAddressType.unix);

    // The subprocess may take some time to start, so retry setting up the
    // connection a few times.
    Socket? client;
    while (true) {
      try {
        client = await Socket.connect(serverAddress, 0);
        break;
      } catch (e, st) {
        if (retries <= 0) {
          rethrow;
        }
        retries--;
      }
      await Future.delayed(retryDelay);
    }

    List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    List<int> data = [];
    var completer = Completer<void>();
    client.listen(data.addAll, onDone: () {
      Expect.listEquals(sendData, data);
      completer.complete();
    });
    client.add(sendData);
    await client.close();
    await completer.future;
    client.destroy();
    var exitCode = await process.exitCode;
    process = null;
    Expect.equals(exitCode, 0);
  } catch (e, st) {
    Expect.fail('Failed with exception:\n$e\n$st');
  } finally {
    process?.kill(ProcessSignal.sigkill);
    await stdoutFuture;
    await stderrFuture;
    await process?.exitCode;
  }
}

Future testExistingFile(String name) async {
  // Test that a leftover file(In case of previous process being killed and
  // finalizer doesn't clean up the file) will be cleaned up and bind() should
  // be able to bind to the socket.
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  // Create a file with the same name
  File(address.address).createSync();
  try {
    ServerSocket server = await ServerSocket.bind(address, 0);
    server.close();
  } catch (e) {
    Expect.type<SocketException>(e);
    return;
  }
  Expect.fail("bind should fail with existing file");
}

Future testSetSockOpt(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  var server = await ServerSocket.bind(address, 0, shared: false);

  var sub;
  sub = server.listen((s) {
    sub.cancel();
    server.close();
  });

  var socket = await Socket.connect(address, server.port);
  socket.write(" socket content");

  // Get some socket options.
  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelTcp, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelUdp, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelIPv4, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelIPv6, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelSocket, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Protocol not available'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option = RawSocketOption.fromBool(
          RawSocketOption.IPv4MulticastInterface, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option = RawSocketOption.fromBool(
          RawSocketOption.IPv6MulticastInterface, i, false);
      var result = socket.getRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  // Set some socket options
  try {
    socket.setOption(SocketOption.tcpNoDelay, true);
  } catch (e) {
    Expect.isTrue(e.toString().contains('Operation not supported'));
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelTcp, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelUdp, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelIPv4, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelIPv6, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option =
          RawSocketOption.fromBool(RawSocketOption.levelSocket, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Protocol not available'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option = RawSocketOption.fromBool(
          RawSocketOption.IPv4MulticastInterface, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  for (int i = 0; i < 5; i++) {
    try {
      RawSocketOption option = RawSocketOption.fromBool(
          RawSocketOption.IPv6MulticastInterface, i, false);
      var result = socket.setRawOption(option);
    } catch (e) {
      Expect.isTrue(e.toString().contains('Operation not supported'));
    }
  }

  socket.destroy();
  await server.close();
}

Future testHttpServer(String name) async {
  var address = InternetAddress('$name/sock', type: InternetAddressType.unix);
  var httpServer = await HttpServer.bind(address, 0);

  var sub;
  sub = httpServer.listen((s) {
    sub.cancel();
    httpServer.close();
  });

  var socket = await Socket.connect(address, httpServer.port);

  socket.destroy();
  await httpServer.close();
}

Future testFileMessage(String tempDirPath) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }

  final completer = Completer<bool>();

  final address =
      InternetAddress('$tempDirPath/sock', type: InternetAddressType.unix);
  final server = await RawServerSocket.bind(address, 0, shared: false);

  server.listen((RawSocket socket) async {
    print('server started a socket $socket');
    socket.listen((e) {
      if (e == RawSocketEvent.read) {
        final SocketMessage? message = socket.readMessage();
        if (message == null) {
          return;
        }
        print('server received message $message');
        final String messageData = String.fromCharCodes(message.data);
        print('server received messageData $messageData');
        if (messageData == 'EmptyMessage') {
          Expect.equals('EmptyMessage'.length, message.data.length);
          Expect.isTrue(message.controlMessages.isEmpty);
          return;
        }
        Expect.equals('Hello', messageData);
        Expect.equals('Hello'.length, message.data.length);
        Expect.equals(1, message.controlMessages.length);
        final SocketControlMessage controlMessage = message.controlMessages[0];
        final handles = controlMessage.extractHandles();
        Expect.isNotNull(handles);
        Expect.equals(1, handles.length);
        final receivedFile = handles[0].toFile();
        receivedFile.writeStringSync('Hello, server!\n');
        print("server has written to the $receivedFile file");
        socket.write('abc'.codeUnits);
      } else if (e == RawSocketEvent.readClosed) {
        print('server socket got readClosed');
        socket.close();
        server.close();
      }
    });
  });

  final file = File('$tempDirPath/myfile.txt');
  final randomAccessFile = file.openSync(mode: FileMode.write);
  // Send a message with sample file.
  final socket = await RawSocket.connect(address, 0);
  socket.listen((e) {
    if (e == RawSocketEvent.write) {
      randomAccessFile.writeStringSync('Hello, client!\n');
      socket.sendMessage(<SocketControlMessage>[
        SocketControlMessage.fromHandles(
            <ResourceHandle>[ResourceHandle.fromFile(randomAccessFile)])
      ], 'Hello'.codeUnits);
      print('client sent a message');
      socket.sendMessage(<SocketControlMessage>[], 'EmptyMessage'.codeUnits);
      print('client sent a message without control data');
    } else if (e == RawSocketEvent.read) {
      final data = socket.read();
      if (data == null) {
        return;
      }
      Expect.equals('abc', String.fromCharCodes(data));
      Expect.equals(
          'Hello, client!\nHello, server!\n', file.readAsStringSync());
      socket.close();
      completer.complete(true);
    }
  });

  return completer.future;
}

Future testTooLargeControlMessage(String tempDirPath) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }
  final completer = Completer<bool>();
  final address =
      InternetAddress('$tempDirPath/sock', type: InternetAddressType.unix);
  final server = await RawServerSocket.bind(address, 0, shared: false);

  server.listen((RawSocket socket) async {
    print('server started a socket $socket');
    socket.listen((e) {
      if (e == RawSocketEvent.read) {
        throw "Server should not receive request from the client";
      } else if (e == RawSocketEvent.readClosed) {
        socket.close();
        server.close();
      }
    });
  });

  final file = File('$tempDirPath/myfile.txt');
  final randomAccessFile = file.openSync(mode: FileMode.write);
  // Send a message with sample file.
  final socket = await RawSocket.connect(address, 0);

  runZonedGuarded(
      () => socket.listen((e) {
            if (e == RawSocketEvent.write) {
              randomAccessFile.writeStringSync('Hello, client!\n');
              const int largeHandleCount = 1024;
              final manyResourceHandles = List<ResourceHandle>.filled(
                  largeHandleCount, ResourceHandle.fromFile(randomAccessFile));
              socket.sendMessage(<SocketControlMessage>[
                SocketControlMessage.fromHandles(manyResourceHandles)
              ], 'Hello'.codeUnits);
              server.close();
              socket.close();
            }
          }), (e, st) {
    print('Got expected unhandled exception $e $st');
    Expect.equals(true, e is SocketException);
    completer.complete(true);
  });

  return completer.future;
}

Future testFileMessageWithShortRead(String tempDirPath) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }

  final completer = Completer<bool>();

  final address =
      InternetAddress('$tempDirPath/sock', type: InternetAddressType.unix);
  final server = await RawServerSocket.bind(address, 0, shared: false);

  server.listen((RawSocket socket) async {
    print('server started a socket $socket');
    socket.listen((e) {
      if (e == RawSocketEvent.read) {
        Expect.throws(
            () => socket.readMessage(0),
            (e) =>
                e is ArgumentError &&
                e.toString().contains('Illegal length 0'));
        final SocketMessage? message = socket.readMessage(/*count=*/ 1);
        if (message == null) {
          return;
        }
        print('server received message $message');
        final String messageData = String.fromCharCodes(message.data);
        print('messageData: $messageData');
        if (messageData[0] == 'H') {
          Expect.equals(1, message.controlMessages.length);
          final SocketControlMessage controlMessage =
              message.controlMessages[0];
          final handles = controlMessage.extractHandles();
          Expect.isNotNull(handles);
          Expect.equals(1, handles.length);
          final handlesAgain = controlMessage.extractHandles();
          Expect.isNotNull(handlesAgain);
          Expect.equals(1, handlesAgain.length);
          handles[0].toFile().writeStringSync('Hello, server!\n');
          socket.write('abc'.codeUnits);
        } else {
          Expect.equals('i', messageData[0]);
          Expect.equals(0, message.controlMessages.length);
        }
      } else if (e == RawSocketEvent.readClosed) {
        print('server socket got readClosed');
        socket.close();
        server.close();
      }
    });
  });

  final file = File('$tempDirPath/myfile.txt');
  final randomAccessFile = file.openSync(mode: FileMode.write);
  // Send a message with sample file.
  final socket = await RawSocket.connect(address, 0);
  socket.listen((e) {
    if (e == RawSocketEvent.write) {
      randomAccessFile.writeStringSync('Hello, client!\n');
      socket.sendMessage(<SocketControlMessage>[
        SocketControlMessage.fromHandles(
            <ResourceHandle>[ResourceHandle.fromFile(randomAccessFile)])
      ], 'Hi'.codeUnits);
      print('client sent a message');
    } else if (e == RawSocketEvent.read) {
      final data = socket.read();
      if (data == null) {
        return;
      }
      Expect.equals('abc', String.fromCharCodes(data));
      Expect.equals(
          'Hello, client!\nHello, server!\n', file.readAsStringSync());
      socket.close();
      completer.complete(true);
    }
  });

  return completer.future;
}

Future<RawServerSocket> createTestServer() async {
  final server = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
  return server
    ..listen((client) {
      String receivedData = "";

      client.writeEventsEnabled = false;
      client.listen((event) {
        switch (event) {
          case RawSocketEvent.READ:
            assert(client.available() > 0);
            final buffer = client.read(200)!;
            receivedData += String.fromCharCodes(buffer);
            break;
          case RawSocketEvent.READ_CLOSED:
            client.close();
            server.close();
            break;
          case RawSocketEvent.CLOSED:
            Expect.equals(
                "Hello, client 1!\nHello, client 2!\nHello, server!\n",
                receivedData);
            break;
          default:
            throw "Unexpected event $event";
        }
      }, onError: (e) {
        print("client ERROR $e");
      });
    });
}

Future testSocketMessage(String uniqueName) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }

  final address =
      InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
  final server = await RawServerSocket.bind(address, 0, shared: false);

  server.listen((RawSocket socket) async {
    socket.listen((e) {
      switch (e) {
        case RawSocketEvent.read:
          final SocketMessage? message = socket.readMessage();
          if (message == null) {
            return;
          }
          Expect.equals('Hello', String.fromCharCodes(message.data));
          Expect.equals(1, message.controlMessages.length);
          final SocketControlMessage controlMessage =
              message.controlMessages[0];
          final handles = controlMessage.extractHandles();
          Expect.isNotNull(handles);
          Expect.equals(1, handles.length);
          final receivedSocket = handles[0].toRawSocket();
          receivedSocket.write('Hello, server!\n'.codeUnits);
          socket.write('server replied'.codeUnits);
          receivedSocket.close();
          break;
        case RawSocketEvent.readClosed:
          socket.close();
          server.close();
          break;
      }
    });
  });

  final RawServerSocket testServer = await createTestServer();
  final testSocket = await RawSocket.connect("127.0.0.1", testServer.port);

  // Send a message with opened [testSocket] socket.
  final socket = await RawSocket.connect(address, 0);
  socket.listen((e) {
    switch (e) {
      case RawSocketEvent.write:
        testSocket.write('Hello, client 1!\n'.codeUnits);
        socket.sendMessage(<SocketControlMessage>[
          SocketControlMessage.fromHandles(
              <ResourceHandle>[ResourceHandle.fromRawSocket(testSocket)])
        ], 'Hello'.codeUnits);
        testSocket.write('Hello, client 2!\n'.codeUnits);
        break;
      case RawSocketEvent.read:
        final data = socket.read();
        if (data == null) {
          return;
        }

        final dataString = String.fromCharCodes(data);
        Expect.equals('server replied', dataString);
        socket.close();
        testSocket.close();
        testServer.close();
    }
  });
}

Future testStdioMessage(String tempDirPath, {bool caller: false}) async {
  if (!Platform.isLinux && !Platform.isAndroid) {
    return;
  }
  if (caller) {
    final process = await Process.start(Platform.resolvedExecutable,
        <String>[Platform.script.toFilePath(), '--start-stdio-message-test']);
    String processStdout = "";
    String processStderr = "";
    process.stdout.transform(utf8.decoder).listen((line) {
      processStdout += line;
      print('stdout:>$line<');
    });
    process.stderr.transform(utf8.decoder).listen((line) {
      processStderr += line;
      print('stderr:>$line<');
    });
    process.stdin.writeln('Caller wrote to stdin');

    Expect.equals(0, await process.exitCode);
    Expect.equals("client sent a message\nHello, server!\n", processStdout);
    Expect.equals(
        "client wrote to stderr\nHello, server too!\n", processStderr);
    return;
  }

  final address =
      InternetAddress('$tempDirPath/sock', type: InternetAddressType.unix);
  final server = await RawServerSocket.bind(address, 0, shared: false);

  server.listen((RawSocket socket) async {
    socket.listen((e) {
      if (e == RawSocketEvent.read) {
        final SocketMessage? message = socket.readMessage();
        if (message == null) {
          return;
        }
        Expect.equals('Hello', String.fromCharCodes(message.data));
        Expect.equals(message.controlMessages.length, 1);
        final SocketControlMessage controlMessage = message.controlMessages[0];
        final handles = controlMessage.extractHandles();
        Expect.isNotNull(handles);
        Expect.equals(3, handles.length);
        final receivedStdin = handles[0].toFile();
        final receivedString = String.fromCharCodes(receivedStdin.readSync(32));
        Expect.equals('Caller wrote to stdin\n', receivedString);
        final receivedStdout = handles[1].toFile();
        receivedStdout.writeStringSync('Hello, server!\n');
        final receivedStderr = handles[2].toFile();
        receivedStderr.writeStringSync('Hello, server too!\n');
        socket.write('abc'.codeUnits);
      } else if (e == RawSocketEvent.readClosed) {
        socket.close();
        server.close();
      }
    });
  });

  final file = File('$tempDirPath/myfile.txt');
  final randomAccessFile = file.openSync(mode: FileMode.write);
  // Send a message with sample file.
  var socket = await RawSocket.connect(address, 0);
  socket.listen((e) {
    if (e == RawSocketEvent.write) {
      socket.sendMessage(<SocketControlMessage>[
        SocketControlMessage.fromHandles(<ResourceHandle>[
          ResourceHandle.fromStdin(stdin),
          ResourceHandle.fromStdout(stdout),
          ResourceHandle.fromStdout(stderr)
        ])
      ], 'Hello'.codeUnits);
      stdout.writeln('client sent a message');
      stderr.writeln('client wrote to stderr');
    } else if (e == RawSocketEvent.read) {
      final data = socket.read();
      if (data == null) {
        return;
      }
      Expect.equals('abc', String.fromCharCodes(data));
      socket.close();
    }
  });
}

void main(List<String> args) async {
  runZonedGuarded(() async {
    if (args.length > 0 && args[0] == '--start-stdio-message-test') {
      await withTempDir('unix_socket_test', (Directory dir) async {
        await testStdioMessage('${dir.path}', caller: false);
      });
      return;
    }

    await withTempDir('unix_socket_test', (Directory dir) async {
      await testAddress('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testBind('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testBindShared('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testListenCloseListenClose('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testSourceAddressConnect('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testAbstractAddress(dir.uri.pathSegments.last);
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testExistingFile('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testSetSockOpt('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testHttpServer('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testShortAbstractAddress(dir.uri.pathSegments.last);
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testFileMessage('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testFileMessageWithShortRead('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testTooLargeControlMessage('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testSocketMessage('${dir.path}');
    });
    await withTempDir('unix_socket_test', (Directory dir) async {
      await testStdioMessage('${dir.path}', caller: true);
    });
  }, (e, st) {
    if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
      Expect.fail("Unexpected exception $e is thrown");
    } else {
      Expect.isTrue(e is SocketException);
      Expect.isTrue(e.toString().contains('not available'));
    }
  });
}
