// Copyright (c) 2013, 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.
//
// OtherResources=certificates/server_chain.pem
// OtherResources=certificates/server_key.pem
// OtherResources=secure_socket_renegotiate_client.dart

// @dart = 2.9

// This test verifies that client certificates work, if the client and server
// are in separate processes, and that connection renegotiation works, and
// can request a client certificate to be sent.

import "dart:async";
import "dart:convert";
import "dart:io";

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

const HOST_NAME = "localhost";
String localFile(path) => Platform.script.resolve(path).toFilePath();

SecurityContext serverContext = new SecurityContext()
  ..useCertificateChain(localFile('certificates/server_chain.pem'))
  ..usePrivateKey(localFile('certificates/server_key.pem'),
      password: 'dartdart');

Future<SecureServerSocket> runServer() {
  return SecureServerSocket.bind(HOST_NAME, 0, serverContext)
      .then((SecureServerSocket server) {
    server.listen((SecureSocket socket) {
      Expect.isNull(socket.peerCertificate);

      StreamIterator<String> input = new StreamIterator(
          utf8.decoder.bind(socket).transform(new LineSplitter()));
      input.moveNext().then((success) {
        Expect.isTrue(success);
        Expect.equals('first', input.current);
        socket.writeln('first reply');
        return input.moveNext();
      }).then((success) {
        Expect.isTrue(success);
        Expect.equals('renegotiated', input.current);
        Expect.isNull(socket.peerCertificate);
        socket.renegotiate(
            requestClientCertificate: true,
            requireClientCertificate: true,
            useSessionCache: false);
        socket.writeln('server renegotiated');
        return input.moveNext();
      }).then((success) {
        Expect.isTrue(success);
        Expect.equals('second', input.current);
        X509Certificate certificate = socket.peerCertificate;
        Expect.isNotNull(certificate);
        Expect.equals("CN=localhost", certificate.subject);
        Expect.equals("CN=myauthority", certificate.issuer);
        server.close();
        socket.close();
      });
    });
    return server;
  });
}

void main() {
  runServer().then((SecureServerSocket server) {
    var clientScript = Platform.script
        .resolve('secure_socket_renegotiate_client.dart')
        .toFilePath();
    Process.run(
            Platform.executable,
            []
              ..addAll(Platform.executableArguments)
              ..addAll([clientScript, server.port.toString()]))
        .then((ProcessResult result) {
      if (result.exitCode != 0) {
        print("Client failed, stdout:");
        print(result.stdout);
        print("  stderr:");
        print(result.stderr);
        Expect.fail('Client subprocess exit code: ${result.exitCode}');
      }
    });
  });
}
