// 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:async';
import 'dart:convert' show ascii, utf8;
import 'dart:io';

import 'package:http2/multiprotocol_server.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';

void main() {
  var context = SecurityContext()
    ..useCertificateChain('test/certificates/server_chain.pem')
    ..usePrivateKey('test/certificates/server_key.pem', password: 'dartdart');

  group('multiprotocol-server', () {
    test('http/1.1', () async {
      const Count = 2;

      var server = await MultiProtocolHttpServer.bind('localhost', 0, context);
      var requestNr = 0;
      server.startServing(
          expectAsync1((HttpRequest request) async {
            await handleHttp11Request(request, requestNr++);
            if (requestNr == Count) {
              await server.close();
            }
          }, count: Count),
          expectAsync1((ServerTransportStream stream) {}, count: 0));

      var client = HttpClient();
      client.badCertificateCallback = (_, __, ___) => true;
      for (var i = 0; i < Count; i++) {
        await makeHttp11Request(server, client, i);
      }
    });

    test('http/2', () async {
      const Count = 2;

      var server = await MultiProtocolHttpServer.bind('localhost', 0, context);
      var requestNr = 0;
      server.startServing(
          expectAsync1((HttpRequest request) {}, count: 0),
          expectAsync1((ServerTransportStream stream) async {
            await handleHttp2Request(stream, requestNr++);
            if (requestNr == Count) {
              await server.close();
            }
          }, count: Count));

      var socket = await SecureSocket.connect('localhost', server.port,
          onBadCertificate: (_) => true,
          supportedProtocols: ['http/1.1', 'h2']);
      var connection = ClientTransportConnection.viaSocket(socket);
      for (var i = 0; i < Count; i++) {
        await makeHttp2Request(server, connection, i);
      }
      await connection.finish();
    });
  });
}

Future makeHttp11Request(
    MultiProtocolHttpServer server, HttpClient client, int i) async {
  var request =
      await client.getUrl(Uri.parse('https://localhost:${server.port}/abc$i'));
  var response = await request.close();
  var body = await response.cast<List<int>>().transform(utf8.decoder).join('');
  expect(body, 'answer$i');
}

Future handleHttp11Request(HttpRequest request, int i) async {
  expect(request.uri.path, '/abc$i');
  await request.drain<void>();
  request.response.write('answer$i');
  await request.response.close();
}

Future makeHttp2Request(MultiProtocolHttpServer server,
    ClientTransportConnection connection, int i) async {
  expect(connection.isOpen, true);
  var headers = [
    Header.ascii(':method', 'GET'),
    Header.ascii(':scheme', 'https'),
    Header.ascii(':authority', 'localhost:${server.port}'),
    Header.ascii(':path', '/abc$i'),
  ];

  var stream = connection.makeRequest(headers, endStream: true);
  var si = StreamIterator(stream.incomingMessages);

  expect(await si.moveNext(), true);
  expect(si.current, isA<HeadersStreamMessage>());
  var responseHeaders = getHeaders(si.current as HeadersStreamMessage);
  expect(responseHeaders[':status'], '200');

  expect(await si.moveNext(), true);
  expect(ascii.decode((si.current as DataStreamMessage).bytes), 'answer$i');

  expect(await si.moveNext(), false);
}

Future handleHttp2Request(ServerTransportStream stream, int i) async {
  var si = StreamIterator(stream.incomingMessages);

  expect(await si.moveNext(), true);
  expect(si.current, isA<HeadersStreamMessage>());
  var headers = getHeaders(si.current as HeadersStreamMessage);

  expect(headers[':path'], '/abc$i');
  expect(await si.moveNext(), false);

  stream.outgoingMessages.add(HeadersStreamMessage([
    Header.ascii(':status', '200'),
  ]));

  stream.outgoingMessages.add(DataStreamMessage(ascii.encode('answer$i')));
  await stream.outgoingMessages.close();
}

Map<String, String> getHeaders(HeadersStreamMessage headers) {
  var map = <String, String>{};
  for (var h in headers.headers) {
    map.putIfAbsent(ascii.decode(h.name), () => ascii.decode(h.value));
  }
  return map;
}
