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

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