// 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.

// VMOptions=--long-ssl-cert-evaluation

// This test verifies that lost of connection during handshake doesn't cause
// vm crashes.

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

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

String getFilename(String path) => Platform.script.resolve(path).toFilePath();

final SecurityContext serverSecurityContext = () {
  final context = SecurityContext();
  context
      .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
  context.useCertificateChainBytes(
      File(getFilename('localhost.crt')).readAsBytesSync());
  return context;
}();

final SecurityContext clientSecurityContext = () {
  final context = SecurityContext(withTrustedRoots: true);
  context.setTrustedCertificatesBytes(
      File(getFilename('localhost.crt')).readAsBytesSync());
  return context;
}();

void main(List<String> args) async {
  if (args.length >= 1 && args[0] == 'server') {
    final server =
        await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
    print('ok ${server.port}');
    server.listen((socket) {
      print('server: got connection');
      socket.close();
    });
    await Future.delayed(Duration(seconds: 2));
    print('server: exiting');
    exit(1);
  }

  asyncStart();

  final serverProcess = await Process.start(
      Platform.executable, [Platform.script.toFilePath(), 'server']);
  final serverPortCompleter = Completer<int>();

  serverProcess.stdout
      .transform(utf8.decoder)
      .transform(LineSplitter())
      .listen((line) {
    print('server stdout: $line');
    if (line.startsWith('ok')) {
      serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
    }
  });
  serverProcess.stderr
      .transform(utf8.decoder)
      .transform(LineSplitter())
      .listen((line) => print('server stderr: $line'));

  int port = await serverPortCompleter.future;

  final errorCompleter = Completer();
  await runZoned(() async {
    var socket = await SecureSocket.connect('localhost', port,
        context: clientSecurityContext);
    socket.write(<int>[1, 2, 3]);
  }, onError: (e) async {
    // Even if server disconnects during later parts of handshake, since
    // TLS v1.3 client might not notice it until attempt to communicate with
    // the server.
    print('thrownException: $e');
    errorCompleter.complete(e);
  });
  Expect.isTrue((await errorCompleter.future) is SocketException);
  await serverProcess.kill();

  asyncEnd();
}
