// 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.

library service_io;

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:logging/logging.dart';
import 'package:observatory/service_common.dart';

// Export the service library.
export 'package:observatory/service_common.dart';

class _IOWebSocket implements CommonWebSocket {
  WebSocket? _webSocket;

  Future<void> connect(WebSocketVMTarget target, void onOpen(),
      void onMessage(dynamic data), void onError(), void onClose()) async {
    try {
      _webSocket = await WebSocket.connect(target.networkAddress);
      _webSocket!.listen(onMessage,
          onError: (dynamic) => onError(),
          onDone: onClose,
          cancelOnError: true);
      onOpen();
    } catch (_) {
      onError();
    }
  }

  bool get isOpen =>
      (_webSocket != null) && (_webSocket!.readyState == WebSocket.open);

  void send(dynamic data) {
    _webSocket!.add(data);
  }

  void close() {
    _webSocket?.close();
  }

  Future<ByteData> nonStringToByteData(dynamic data) {
    assert(data is Uint8List);
    Logger.root.info('Binary data size in bytes: ${data.lengthInBytes}');
    return new Future.sync(() =>
        new ByteData.view(data.buffer, data.offsetInBytes, data.lengthInBytes));
  }
}

/// The [WebSocketVM] communicates with a Dart VM over WebSocket.
class WebSocketVM extends CommonWebSocketVM {
  WebSocketVM(WebSocketVMTarget target) : super(target, new _IOWebSocket());
}
