// Copyright (c) 2015, 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.

import 'dart:io';
import 'dart:convert';

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';

const String NAME_LENGTH_ERROR =
    'Length of protocol must be between 1 and 255';

const String MESSAGE_LENGTH_ERROR =
    'The maximum message length supported is 2^13-1';

String localFile(path) => Platform.script.resolve(path).toFilePath();

SecurityContext clientContext() => new SecurityContext()
  ..setTrustedCertificatesSync(localFile('certificates/trusted_certs.pem'));

SecurityContext serverContext() => new SecurityContext()
  ..useCertificateChainSync(localFile('certificates/server_chain.pem'))
  ..usePrivateKeySync(localFile('certificates/server_key.pem'),
                      password: 'dartdart');

// Tests that client/server with same protocol can securely establish a
// connection, negotiate the protocol and can send data to each other.
void testSuccessfulAlpnNegotiationConnection(List<String> clientProtocols,
                                             List<String> serverProtocols,
                                             String selectedProtocol) {
  asyncStart();
  var sContext = serverContext()..setAlpnProtocols(serverProtocols, true);
  SecureServerSocket.bind('localhost', 0, sContext)
     .then((SecureServerSocket server) {

    asyncStart();
    server.first.then((SecureSocket socket) {
      Expect.equals(selectedProtocol, socket.selectedProtocol);
      socket..write('server message')..close();
      socket.transform(ASCII.decoder).join('').then((String s) {
        Expect.equals('client message', s);
        asyncEnd();
      });
    });

    asyncStart();
    SecureSocket.connect('localhost', server.port, context: clientContext(),
        supportedProtocols: clientProtocols).then((socket) {
      Expect.equals(selectedProtocol, socket.selectedProtocol);
      socket..write('client message')..close();
      socket.transform(ASCII.decoder).join('').then((String s) {
        Expect.equals('server message', s);
        server.close();
        asyncEnd();
      });
    });

    asyncEnd();
  });
}

void testInvalidArgument(List<String> protocols, String errorIncludes) {
  testInvalidArgumentServerContext(protocols, errorIncludes);
  testInvalidArgumentClientContext(protocols, errorIncludes);
  testInvalidArgumentClientConnect(protocols, errorIncludes);
}

void testInvalidArgumentServerContext(List<String> protocols,
                                      String errorIncludes) {
  Expect.throws(() => serverContext().setAlpnProtocols(protocols, true), (e) {
    Expect.isTrue(e is ArgumentError);
    Expect.isTrue(e.toString().contains(errorIncludes));
    return true;
  });
}

void testInvalidArgumentClientContext(List<String> protocols,
                                      String errorIncludes) {
  Expect.throws(() => clientContext().setAlpnProtocols(protocols, false), (e) {
    Expect.isTrue(e is ArgumentError);
    Expect.isTrue(e.toString().contains(errorIncludes));
    return true;
  });
}

void testInvalidArgumentClientConnect(List<String> protocols,
                                      String errorIncludes) {
  asyncStart();
  var sContext = serverContext()..setAlpnProtocols(['abc'], true);
  SecureServerSocket.bind('localhost', 0, sContext).then((server) async {
    asyncStart();
    server.listen((SecureSocket socket) {
      Expect.fail(
          "Unexpected connection made to server, with bad client argument");
    }, onError: (e) {
      Expect.fail("Unexpected error on server stream: $e");
    }, onDone: () { asyncEnd();});

    asyncStart();
    SecureSocket.connect('localhost', server.port, context: clientContext(),
          supportedProtocols: protocols).then((socket) {
      Expect.fail(
          "Unexpected connection made from client, with bad client argument");
    }, onError: (e) {
      Expect.isTrue(e is ArgumentError);
      Expect.isTrue(e.toString().contains(errorIncludes));
      server.close();
      asyncEnd();
    });
    asyncEnd();
  });
}

main() {
  final longname256 = 'p' * 256;
  final String longname255 = 'p' * 255;
  final String strangelongname255 = 'ø' + 'p' * 253;
  final String strangelongname256 = 'ø' + 'p' * 254;

  // This produces a message of (1 << 13) - 2 bytes. 2^12 -1 strings are each
  // encoded by 1 length byte and 1 ascii byte.
  final List<String> manyProtocols = new Iterable.generate(
      (1 << 12) - 1, (i) => '0').toList();

  // This produces a message of (1 << 13) bytes. 2^12 strings are each
  // encoded by 1 length byte and 1 ascii byte.
  final List<String> tooManyProtocols = new Iterable.generate(
      (1 << 12), (i) => '0').toList();

  // Protocols are in order of decreasing priority. The server will select
  // the first protocol from its list that has a match in the client list.
  // Test successful negotiation, including priority.
  testSuccessfulAlpnNegotiationConnection(['a'],
                                          ['a'],
                                          'a');

  testSuccessfulAlpnNegotiationConnection([longname255],
                                          [longname255],
                                          longname255);

  testSuccessfulAlpnNegotiationConnection([strangelongname255],
                                          [strangelongname255],
                                          strangelongname255);
  testSuccessfulAlpnNegotiationConnection(manyProtocols,
                                          manyProtocols,
                                          '0');
  testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
                                          ['a', 'b', 'c'],
                                          'a');

  testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
                                          ['c'],
                                          'c');

  // Server precedence.
  testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
                                          ['c', 'b', 'a'],
                                          'c');

  testSuccessfulAlpnNegotiationConnection(['c'],
                                          ['a', 'b', 'c'],
                                          'c');

  testSuccessfulAlpnNegotiationConnection(['s1', 'b', 'e1'],
                                          ['s2', 'b', 'e2'],
                                          'b');
  // Test no protocol negotiation support
  testSuccessfulAlpnNegotiationConnection(null,
                                          null,
                                          null);

  testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
                                          null,
                                          null);

  testSuccessfulAlpnNegotiationConnection(null,
                                          ['a', 'b', 'c'],
                                          null);

  testSuccessfulAlpnNegotiationConnection([],
                                          [],
                                          null);

  testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
                                          [],
                                          null);

  testSuccessfulAlpnNegotiationConnection([],
                                          ['a', 'b', 'c'],
                                          null);

  // Test non-overlapping protocols.  The ALPN RFC says the connection
  // should be terminated, but OpenSSL continues as if no ALPN is present.
  // Issue  https://github.com/dart-lang/sdk/issues/23580
  // Chromium issue https://code.google.com/p/chromium/issues/detail?id=497770
  testSuccessfulAlpnNegotiationConnection(['a'], ['b'], null);

  // Test too short / too long protocol names.
  testInvalidArgument([longname256], NAME_LENGTH_ERROR);
  testInvalidArgument([strangelongname256], NAME_LENGTH_ERROR);
  testInvalidArgument([''], NAME_LENGTH_ERROR);
  testInvalidArgument(tooManyProtocols, MESSAGE_LENGTH_ERROR);
}
