// 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';

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();
}

// Create socket in temp directory
Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
  var tempDir = Directory.systemTemp.createTempSync(prefix);
  try {
    await test(tempDir);
  } finally {
    tempDir.deleteSync(recursive: true);
  }
}

void main() async {
  try {
    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);
    });
  } catch (e) {
    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'));
    }
  }
}
