// 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
// OtherResources=localhost.key
// OtherResources=localhost.crt

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