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

// 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(
          socket.transform(utf8.decoder).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.toFilePath().replaceFirst("_test.dart", "_client.dart");
    Expect.isTrue(clientScript.endsWith("_client.dart"));
    Process
        .run(Platform.executable, [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}');
      }
    });
  });
}
