// Copyright (c) 2014, 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 'package:http/http.dart' as http;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:test/test.dart';

Map<String, String> get _handshakeHeaders => {
      "Upgrade": "websocket",
      "Connection": "Upgrade",
      "Sec-WebSocket-Key": "x3JJHMbDL1EzLkh9GBhXDw==",
      "Sec-WebSocket-Version": "13"
    };

void main() {
  test("can communicate with a dart:io WebSocket client", () async {
    var server = await shelf_io.serve(webSocketHandler((webSocket) {
      webSocket.sink.add("hello!");
      webSocket.stream.first.then((request) {
        expect(request, equals("ping"));
        webSocket.sink.add("pong");
        webSocket.sink.close();
      });
    }), "localhost", 0);

    try {
      var webSocket = await WebSocket.connect('ws://localhost:${server.port}');
      var n = 0;
      await webSocket.listen((message) {
        if (n == 0) {
          expect(message, equals("hello!"));
          webSocket.add("ping");
        } else if (n == 1) {
          expect(message, equals("pong"));
          webSocket.close();
          server.close();
        } else {
          fail("Only expected two messages.");
        }
        n++;
      }).asFuture();
    } finally {
      await server.close();
    }
  });

  test("negotiates the sub-protocol", () async {
    var server = await shelf_io.serve(
        webSocketHandler((webSocket, protocol) {
          expect(protocol, equals("two"));
          webSocket.sink.close();
        }, protocols: ["three", "two", "x"]),
        "localhost",
        0);

    try {
      var webSocket = await WebSocket.connect('ws://localhost:${server.port}',
          protocols: ["one", "two", "three"]);
      expect(webSocket.protocol, equals("two"));
      return webSocket.close();
    } finally {
      await server.close();
    }
  });

  group("with a set of allowed origins", () {
    var server;
    var url;
    setUp(() async {
      server = await shelf_io.serve(
          webSocketHandler((webSocket) {
            webSocket.sink.close();
          }, allowedOrigins: ["pub.dartlang.org", "GoOgLe.CoM"]),
          "localhost",
          0);
      url = 'http://localhost:${server.port}/';
    });

    tearDown(() => server.close());

    test("allows access with an allowed origin", () {
      var headers = _handshakeHeaders;
      headers['Origin'] = 'pub.dartlang.org';
      expect(http.get(url, headers: headers), hasStatus(101));
    });

    test("forbids access with a non-allowed origin", () {
      var headers = _handshakeHeaders;
      headers['Origin'] = 'dartlang.org';
      expect(http.get(url, headers: headers), hasStatus(403));
    });

    test("allows access with no origin", () {
      expect(http.get(url, headers: _handshakeHeaders), hasStatus(101));
    });

    test("ignores the case of the client origin", () {
      var headers = _handshakeHeaders;
      headers['Origin'] = 'PuB.DaRtLaNg.OrG';
      expect(http.get(url, headers: headers), hasStatus(101));
    });

    test("ignores the case of the server origin", () {
      var headers = _handshakeHeaders;
      headers['Origin'] = 'google.com';
      expect(http.get(url, headers: headers), hasStatus(101));
    });
  });

  // Regression test for issue 21894.
  test("allows a Connection header with multiple values", () async {
    var server = await shelf_io.serve(webSocketHandler((webSocket) {
      webSocket.sink.close();
    }), "localhost", 0);

    var url = 'http://localhost:${server.port}/';
    var headers = _handshakeHeaders;
    headers['Connection'] = 'Other-Token, Upgrade';
    expect(http.get(url, headers: headers).whenComplete(server.close),
        hasStatus(101));
  });

  group("HTTP errors", () {
    var server;
    var url;
    setUp(() async {
      server = await shelf_io.serve(webSocketHandler((_) {
        fail("should not create a WebSocket");
      }), "localhost", 0);
      url = 'http://localhost:${server.port}/';
    });

    tearDown(() => server.close());

    test("404s for non-GET requests", () {
      expect(http.delete(url, headers: _handshakeHeaders), hasStatus(404));
    });

    test("404s for non-Upgrade requests", () {
      var headers = _handshakeHeaders;
      headers.remove('Connection');
      expect(http.get(url, headers: headers), hasStatus(404));
    });

    test("404s for non-websocket upgrade requests", () {
      var headers = _handshakeHeaders;
      headers['Upgrade'] = 'fblthp';
      expect(http.get(url, headers: headers), hasStatus(404));
    });

    test("400s for a missing Sec-WebSocket-Version", () {
      var headers = _handshakeHeaders;
      headers.remove('Sec-WebSocket-Version');
      expect(http.get(url, headers: headers), hasStatus(400));
    });

    test("404s for an unknown Sec-WebSocket-Version", () {
      var headers = _handshakeHeaders;
      headers['Sec-WebSocket-Version'] = '15';
      expect(http.get(url, headers: headers), hasStatus(404));
    });

    test("400s for a missing Sec-WebSocket-Key", () {
      var headers = _handshakeHeaders;
      headers.remove('Sec-WebSocket-Key');
      expect(http.get(url, headers: headers), hasStatus(400));
    });
  });

  test("throws an error if a unary function is provided with protocols", () {
    expect(() => webSocketHandler((_) => null, protocols: ['foo']),
        throwsArgumentError);
  });
}

Matcher hasStatus(int status) => completion(predicate((response) {
      expect(response, new isInstanceOf<http.Response>());
      expect(response.statusCode, equals(status));
      return true;
    }));
