// 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 "dart:async";
import "dart:io";

testEmptyProtocol() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      WebSocketTransformer.upgrade(request).then((websocket) {
        websocket.close();
      });
    });
    WebSocket.connect("ws://127.0.0.1:${server.port}/", protocols: []).then((
      client,
    ) {
      Expect.isNull(client.protocol);
      client.close();
      server.close();
    });
  });
}

testProtocol(List<String> protocols, String used) {
  selector(List<String> receivedProtocols) {
    Expect.listEquals(protocols, receivedProtocols);
    return used;
  }

  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      WebSocketTransformer.upgrade(request, protocolSelector: selector).then((
        websocket,
      ) {
        Expect.equals(used, websocket.protocol);
        websocket.close();
      });
    });
    WebSocket.connect(
      "ws://127.0.0.1:${server.port}/",
      protocols: protocols,
    ).then((client) {
      Expect.equals(used, client.protocol);
      client.close();
      server.close();
    });
  });
}

testProtocolHandler() {
  // Test throwing an error.
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      selector(List<String> receivedProtocols) {
        throw "error";
      }

      WebSocketTransformer.upgrade(request, protocolSelector: selector).then(
        (websocket) {
          Expect.fail('error expected');
        },
        onError: (error) {
          Expect.equals('error', error);
        },
      );
    });
    WebSocket.connect(
      "ws://127.0.0.1:${server.port}/",
      protocols: ["v1.example.com"],
    ).then(
      (client) {
        Expect.fail('error expected');
      },
      onError: (error) {
        server.close();
      },
    );
  });

  // Test returning another protocol.
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      selector(List<String> receivedProtocols) => "v2.example.com";
      WebSocketTransformer.upgrade(request, protocolSelector: selector).then(
        (websocket) {
          Expect.fail('error expected');
        },
        onError: (error) {
          Expect.isTrue(error is WebSocketException);
        },
      );
    });
    WebSocket.connect(
      "ws://127.0.0.1:${server.port}/",
      protocols: ["v1.example.com"],
    ).then(
      (client) {
        Expect.fail('error expected');
      },
      onError: (error) {
        server.close();
      },
    );
  });
}

void main() {
  testEmptyProtocol();
  testProtocol(["v1.example.com", "v2.example.com"], "v1.example.com");
  testProtocol(["v1.example.com", "v2.example.com"], "v2.example.com");
  testProtocolHandler();
}
