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