// 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.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

import "package:expect/expect.dart";
import "package:path/path.dart";
import "dart:async";
import "dart:io";
import "dart:isolate";

const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";

// This test sends corrupt data in the middle of a secure network connection.
// This tests the error handling of RawSecureSocket.
// A RawSocket connection is upgraded to a secure connection, so that we
// have a reference to the underlying socket.  Then we send some
// unencrypted data on it, in the middle of an encrypted data transfer.


// This test creates a server and then connects a client to the server.
// After connecting, the connection is upgraded to a secure connection.
// The client writes data to the server, then writes unencrypted data
// on the underlying socket.  When the server gets the unencrypted data,
// this causes an error in the NSS code.  When the NSS code is in debug
// mode, bad data on the connection can cause an assertion failure, rather
// than an exception.

const messageSize = 1000;


List<int> createTestData() {
  List<int> data = new List<int>(messageSize);
  for (int i = 0; i < messageSize; i++) {
    data[i] = i & 0xff;
  }
  return data;
}


void verifyTestData(List<int> data) {
  Expect.equals(messageSize, data.length);
  List<int> expected = createTestData();
  for (int i = 0; i < messageSize; i++) {
    Expect.equals(expected[i], data[i]);
  }
}


Future runServer(RawSocket client) {
  final completer = new Completer();
  final dataReceived = new List<int>(messageSize);
  int bytesRead = 0;
  client.writeEventsEnabled = false;
  client.listen((event) {
    switch (event) {
      case RawSocketEvent.READ:
        Expect.isTrue(client.available() > 0);
        var buffer = client.read(200);
        dataReceived.setRange(bytesRead, bytesRead + buffer.length, buffer);
        bytesRead += buffer.length;
        if (bytesRead == dataReceived.length) {
          verifyTestData(dataReceived);
        }
        break;
      case RawSocketEvent.WRITE:
        Expect.fail('WRITE event received');
        break;
      case RawSocketEvent.READ_CLOSED:
        Expect.fail('READ_CLOSED event received');
        client.shutdown(SocketDirection.SEND);
        completer.complete(null);
        break;
    }
  },
  onError: (e) {
    Expect.isTrue(e is TlsException);
    Expect.isTrue(e.toString().contains(
        'received a record with an incorrect Message Authentication Code'));
    completer.complete(null);
  });
  return completer.future;
}


Future<RawSocket> runClient(List sockets) {
  final RawSocket baseSocket = sockets[0];
  final RawSecureSocket socket = sockets[1];
  final data = createTestData();
  var completer = new Completer();
  void tryComplete() {
    if (completer != null) {
      completer.complete(null);
      completer = null;
    }
  }

  int bytesWritten = 0;
  socket.listen((event) {
    switch (event) {
      case RawSocketEvent.READ:
        Expect.fail('READ event received');
        break;
      case RawSocketEvent.WRITE:
        if (bytesWritten < data.length) {
          bytesWritten +=  socket.write(data, bytesWritten);
        }
        if (bytesWritten < data.length) {
          socket.writeEventsEnabled = true;
        }
        if (bytesWritten == data.length) {
          baseSocket.write(data, 0, 300);
          socket.shutdown(SocketDirection.SEND);
        }
        break;
      case RawSocketEvent.READ_CLOSED:
        tryComplete();
        break;
    }
  },
  onError: (e) {
    Expect.isTrue(e is IOException);
    tryComplete();
  });
  return completer.future;
}


Future<List> connectClient(int port, bool hostnameInConnect) =>
  RawSocket.connect(HOST_NAME, port)
  .then((socket) =>
    (hostnameInConnect ? RawSecureSocket.secure(socket)
                       : RawSecureSocket.secure(socket, host: HOST_NAME))
    .then((secureSocket) => [socket, secureSocket]));


Future test(bool hostnameInConnect) {
  return RawServerSocket.bind(HOST_NAME, 0)
  .then((server) {
    server.listen((client) {
      RawSecureSocket.secureServer(client, CERTIFICATE)
      .then((secureClient) {
        Expect.throws(() => client.add([0]));
        return runServer(secureClient);
      })
      .then((_) => server.close());
    });

    return connectClient(server.port, hostnameInConnect).then(runClient);
  });
}


main() {
  String certificateDatabase = join(dirname(Platform.script), 'pkcert');
  SecureSocket.initialize(database: certificateDatabase,
                          password: 'dartdart',
                          useBuiltinRoots: false);
  var keepAlive = new ReceivePort();
  Future.wait([test(false), test(true)])
  .then((_) => keepAlive.close());
}
