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

testAddressParse() async {
  print(new InternetAddress("1.0.2.3").rawAddress);
  print(new InternetAddress("1.0.2.3").type);

  print(new InternetAddress("::1").rawAddress);
  print(new InternetAddress("::1").type);

  try {
    print(new InternetAddress("localhost"));
  } catch (e) {
    print(e);
  }
}

testSimpleBind() async {
  var s = await RawServerSocket.bind(InternetAddress.loopbackIPv4, 0);
  print("port = ${s.port}");
  await s.close();
}

testSimpleConnect() async {
  var server = await RawServerSocket.bind(InternetAddress.loopbackIPv4, 0);
  print("server port = ${server.port}");
  server.listen((socket) {
    print("listen socket port = ${socket.port}");
    socket.close();
  });
  var socket = await RawSocket.connect("127.0.0.1", server.port);
  print("socket port = ${socket.port}");
  if (socket.remoteAddress.address != "127.0.0.1" ||
      socket.remoteAddress.type != InternetAddressType.IPv4) {
    throw "Bad remote address ${socket.remoteAddress}";
  }
  if (socket.remotePort is! int) {
    throw "Bad remote port ${socket.remotePort}";
  }
  await server.close();
  await socket.close();
}

testSimpleReadWriteClose() async {
  // This test creates a server and a client connects. The client then
  // writes and the server echos. When the client finishes fully reading the
  // echo, it closes the socket. When the server receives the close event, it
  // closes its end of the socket too.

  const messageSize = 1000;
  int serverReadCount = 0;
  int clientReadCount = 0;

  List<int> createTestData() {
    return new List<int>.generate(messageSize, (index) => index & 0xff);
  }

  void verifyTestData(List<int> data) {
    assert(messageSize == data.length);
    List<int> expected = createTestData();
    for (int i = 0; i < messageSize; i++) {
      assert(expected[i] == data[i]);
    }
  }

  var server = await RawServerSocket.bind(InternetAddress.loopbackIPv4, 0);
  server.listen((client) {
    int bytesRead = 0;
    int bytesWritten = 0;
    bool closedEventReceived = false;
    List<int> data = new List<int>.filled(messageSize, -1);
    bool doneReading = false;

    client.writeEventsEnabled = false;
    client.listen((event) {
      switch (event) {
        case RawSocketEvent.read:
          if (doneReading) {
            break;
          }
          print("client READ event bytesRead = $bytesRead");
          assert(bytesWritten == 0);
          assert(client.available() > 0);
          var buffer = client.read(200)!;
          print("client READ event: read ${buffer.length} more bytes");
          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
          bytesRead += buffer.length;
          if (bytesRead == data.length) {
            verifyTestData(data);
            print("client READ event. Done reading, enabling writes");
            client.writeEventsEnabled = true;
            doneReading = true;
          }
          break;
        case RawSocketEvent.write:
          assert(!client.writeEventsEnabled);
          bytesWritten +=
              client.write(data, bytesWritten, data.length - bytesWritten);
          print("client WRITE event: $bytesWritten written");
          if (bytesWritten < data.length) {
            client.writeEventsEnabled = true;
          }
          if (bytesWritten == data.length) {
            print("client WRITE event: done writing.");
          }
          break;
        case RawSocketEvent.readClosed:
          print("client READ_CLOSED event");
          client.close();
          server.close();
          break;
        case RawSocketEvent.closed:
          assert(!closedEventReceived);
          print("client CLOSED event");
          closedEventReceived = true;
          break;
        default:
          throw "Unexpected event $event";
      }
    }, onError: (e) {
      print("client ERROR $e");
    }, onDone: () {
      assert(closedEventReceived);
    });
  });

  {
    var completer = new Completer();
    var socket = await RawSocket.connect("127.0.0.1", server.port);
    int bytesRead = 0;
    int bytesWritten = 0;
    bool closedEventReceived = false;
    List<int> data = createTestData();

    socket.listen((event) {
      switch (event) {
        case RawSocketEvent.read:
          assert(socket.available() > 0);
          print("server READ event: ${bytesRead} read");
          var buffer = socket.read()!;
          print("server READ event: read ${buffer.length} more bytes");
          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
          bytesRead += buffer.length;
          if (bytesRead == messageSize) {
            print("server READ event: done reading");
            socket.close();
          }
          break;
        case RawSocketEvent.write:
          assert(bytesRead == 0);
          assert(!socket.writeEventsEnabled);
          bytesWritten +=
              socket.write(data, bytesWritten, data.length - bytesWritten);
          print("server WRITE event: ${bytesWritten} written");
          if (bytesWritten < data.length) {
            socket.writeEventsEnabled = true;
          } else {
            print("server WRITE event: done writing");
            data = new List<int>.filled(messageSize, -1);
          }
          break;
        case RawSocketEvent.readClosed:
          print("server READ_CLOSED event");
          verifyTestData(data);
          socket.close();
          break;
        case RawSocketEvent.closed:
          assert(!closedEventReceived);
          print("server CLOSED event");
          closedEventReceived = true;
          break;
        default:
          throw "Unexpected event $event";
      }
    }, onError: (e) {
      print("server ERROR $e");
    }, onDone: () {
      assert(closedEventReceived);
      completer.complete(null);
    });

    return completer.future;
  }
}

testSimpleReadWriteShutdown({required bool dropReads}) async {
  // This test creates a server and a client connects. The client then
  // writes and the server echos. When the server has finished its
  // echo it half-closes. When the client gets the close event is
  // closes fully.

  const messageSize = 1000;
  int serverReadCount = 0;
  int clientReadCount = 0;

  List<int> createTestData() {
    return new List<int>.generate(messageSize, (index) => index & 0xff);
  }

  void verifyTestData(List<int> data) {
    assert(messageSize == data.length);
    List<int> expected = createTestData();
    for (int i = 0; i < messageSize; i++) {
      assert(expected[i] == data[i]);
    }
  }

  var server = await RawServerSocket.bind(InternetAddress.loopbackIPv4, 0);
  server.listen((client) {
    int bytesRead = 0;
    int bytesWritten = 0;
    bool closedEventReceived = false;
    List<int> data = new List<int>.filled(messageSize, -1);
    bool doneReading = false;

    client.writeEventsEnabled = false;
    client.listen((event) {
      switch (event) {
        case RawSocketEvent.read:
          if (doneReading) {
            break;
          }
          if (dropReads) {
            if (serverReadCount != 10) {
              serverReadCount++;
              break;
            } else {
              serverReadCount = 0;
            }
          }
          print("client READ event bytesRead = $bytesRead");
          assert(bytesWritten == 0);
          assert(client.available() > 0);
          var buffer = client.read(200)!;
          print("client READ event: read ${buffer.length} more bytes");
          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
          bytesRead += buffer.length;
          if (bytesRead == data.length) {
            verifyTestData(data);
            print("client READ event. Done reading, enabling writes");
            client.writeEventsEnabled = true;
            doneReading = true;
          }
          break;
        case RawSocketEvent.write:
          assert(!client.writeEventsEnabled);
          bytesWritten +=
              client.write(data, bytesWritten, data.length - bytesWritten);
          print("client WRITE event: $bytesWritten written");
          if (bytesWritten < data.length) {
            client.writeEventsEnabled = true;
          }
          if (bytesWritten == data.length) {
            print("client WRITE event: done writing.");
            client.shutdown(SocketDirection.send);
          }
          break;
        case RawSocketEvent.readClosed:
          print("client READ_CLOSED event");
          server.close();
          break;
        case RawSocketEvent.closed:
          assert(!closedEventReceived);
          print("client CLOSED event");
          closedEventReceived = true;
          break;
        default:
          throw "Unexpected event $event";
      }
    }, onDone: () {
      assert(closedEventReceived);
    });
  });

  {
    var completer = new Completer();
    var socket = await RawSocket.connect("127.0.0.1", server.port);
    int bytesRead = 0;
    int bytesWritten = 0;
    bool closedEventReceived = false;
    List<int> data = createTestData();

    socket.listen((event) {
      switch (event) {
        case RawSocketEvent.read:
          assert(socket.available() > 0);
          if (dropReads) {
            if (clientReadCount != 10) {
              clientReadCount++;
              break;
            } else {
              clientReadCount = 0;
            }
          }
          print("server READ event: ${bytesRead} read");
          var buffer = socket.read()!;
          print("server READ event: read ${buffer.length} more bytes");
          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
          bytesRead += buffer.length;
          break;
        case RawSocketEvent.write:
          assert(bytesRead == 0);
          assert(!socket.writeEventsEnabled);
          bytesWritten +=
              socket.write(data, bytesWritten, data.length - bytesWritten);
          print("server WRITE event: ${bytesWritten} written");
          if (bytesWritten < data.length) {
            socket.writeEventsEnabled = true;
          } else {
            print("server WRITE event: done writing");
            data = new List<int>.filled(messageSize, -1);
          }
          break;
        case RawSocketEvent.readClosed:
          print("server READ_CLOSED event");
          verifyTestData(data);
          socket.close();
          break;
        case RawSocketEvent.closed:
          assert(!closedEventReceived);
          print("server CLOSED event");
          closedEventReceived = true;
          break;
        default:
          throw "Unexpected event $event";
      }
    }, onDone: () {
      assert(closedEventReceived);
      completer.complete(null);
    });

    return completer.future;
  }
}

Future testProcess() async {
  String exe = Platform.resolvedExecutable;
  print("Running $exe --version");
  Process p = await Process.start(exe, ["--version"]);
  p.stderr.transform(utf8.decoder).listen(print);
  int code = await p.exitCode;
  print("$exe --version exited with code $code");
}

void testProcessRunSync() {
  String exe = Platform.resolvedExecutable;
  print("Running $exe --version");
  var result = Process.runSync(exe, ["--version"]);
  print("$exe --version exited with code ${result.exitCode}");
  print("$exe --version had stdout = '${result.stdout}'");
  print("$exe --version had stderr = '${result.stderr}'");
}

Future testKill() async {
  String exe = Platform.resolvedExecutable;
  String script = Platform.script.path;
  print("Running $exe $script");
  Process p = await Process.start(exe, [script, "infinite-loop"]);
  await new Future.delayed(const Duration(seconds: 1));
  p.kill();
  int code = await p.exitCode;
  print("$exe $script exited with code $code");
}

Future testLs(String path) async {
  Stream<FileSystemEntity> stream = (new Directory(path)).list();
  await for (FileSystemEntity fse in stream) {
    print(fse.path);
  }
}

void testPlatformEnvironment() {
  Map<String, String> env = Platform.environment;
  for (String k in env.keys) {
    String v = env[k]!;
    print("$k = '$v'");
  }
}

Future testCopy() async {
  final String sourceName = "foo";
  final String destName = "bar";
  Directory tmp = await Directory.systemTemp.createTemp("testCopy");
  File sourceFile = new File("${tmp.path}/$sourceName");
  File destFile = new File("${tmp.path}/$destName");
  List<int> data = new List<int>.generate(10 * 1024, (int i) => i & 0xff);
  await sourceFile.writeAsBytes(data);
  await sourceFile.copy(destFile.path);
  List<int> resultData = await destFile.readAsBytes();
  assert(data.length == resultData.length);
  for (int i = 0; i < data.length; i++) {
    assert(data[i] == resultData[i]);
  }
  await sourceFile.delete();
  await destFile.delete();
  await tmp.delete();
}

Future testRecursiveDelete() async {
  Directory tmp0 = await Directory.systemTemp.createTemp("testRD");
  Directory tmp1 = await tmp0.createTemp("testRD");
  Directory tmp2 = await tmp1.createTemp("testRD");
  File file0 = new File("${tmp0.path}/file");
  File file1 = new File("${tmp1.path}/file");
  File file2 = new File("${tmp2.path}/file");
  List<int> data = new List<int>.generate(10 * 1024, (int i) => i & 0xff);
  await file0.writeAsBytes(data);
  await file1.writeAsBytes(data);
  await file2.writeAsBytes(data);

  await tmp0.delete(recursive: true);

  assert(!await file2.exists());
  assert(!await file1.exists());
  assert(!await file0.exists());
  assert(!await tmp2.exists());
  assert(!await tmp1.exists());
  assert(!await tmp0.exists());
}

bool testFileOpenDirectoryFails() {
  File dir = new File(Directory.systemTemp.path);
  try {
    dir.openSync();
  } on FileSystemException catch (e) {
    return true;
  } catch (e) {
    print("Unexpected Exception: $e");
  }
  return false;
}


Future testListInterfaces() async {
  List<NetworkInterface> interfaces = await NetworkInterface.list();
  print('Found ${interfaces.length} interfaces:');
  for (var iface in interfaces) {
    print('\t$iface');
  }
}

main(List<String> args) async {
  if (args.length >= 1) {
    if (args[0] == "infinite-loop") {
      while (true);
    }
  }

  print("Hello, Fuchsia!");

  print("testAddressParse");
  await testAddressParse();
  print("testAddressParse done");

  print("testSimpleBind");
  await testSimpleBind();
  print("testSimpleBind done");

  print("testSimpleConnect");
  await testSimpleConnect();
  print("testSimpleConnect done");

  print("testSimpleReadWriteClose");
  await testSimpleReadWriteClose();
  print("testSimpleReadWriteClose done");

  print("testSimpleReadWriteShutdown");
  await testSimpleReadWriteShutdown(dropReads: false);
  print("testSimpleReadWriteShutdown done");

  print("lsTest");
  await testLs("/");
  print("lsTest done");

  print("testPlatformEnvironment");
  testPlatformEnvironment();
  print("testPlatformEnvironment done");

  print("testProcess");
  await testProcess();
  print("testProcess done");

  print("testProcessRunSync");
  testProcessRunSync();
  print("testProcessRunSync done");

  print("testKill");
  await testKill();
  print("testKill done");

  print("testCopy");
  await testCopy();
  print("testCopy done");

  print("testRecursiveDelete");
  await testRecursiveDelete();
  print("testRecursiveDelete done");

  print("testFileOpenDirectoryFails");
  bool result = testFileOpenDirectoryFails();
  if (result) {
    print("testFileOpenDirectoryFails done");
  } else {
    print("testFileOpenDirectoryFails FAILED");
  }

  print('testListInterfaces');
  await testListInterfaces();
  print('testListInterfaces done');

  print("Goodbyte, Fuchsia!");
}
