// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of zircon;

// ignore_for_file: public_member_api_docs

class SocketReaderError extends Error {
  final Object error;
  final StackTrace stacktrace;

  SocketReaderError(this.error, this.stacktrace);

  @override
  String toString() => error.toString();
}

typedef SocketReaderReadableHandler = void Function();
typedef SocketReaderErrorHandler = void Function(SocketReaderError error);

class SocketReader {
  Socket get socket => _socket;
  Socket _socket;

  bool get isBound => _socket != null;

  HandleWaiter _waiter;

  SocketReaderReadableHandler onReadable;
  SocketReaderErrorHandler onError;

  void bind(Socket socket) {
    if (isBound) {
      throw ZirconApiError('SocketReader is already bound.');
    }
    _socket = socket;
    _asyncWait();
  }

  Socket unbind() {
    if (!isBound) {
      throw ZirconApiError('SocketReader is not bound');
    }
    _waiter.cancel();
    final Socket result = _socket;
    _socket = null;
    return result;
  }

  void close() {
    if (!isBound) {
      return;
    }
    _waiter.cancel();
    _socket.close();
    _socket = null;
  }

  void _asyncWait() {
    _waiter = _socket.handle
        .asyncWait(Socket.READABLE | Socket.PEER_CLOSED, _handleWaitComplete);
  }

  void _errorSoon(SocketReaderError error) {
    if (onError == null) {
      return;
    }
    scheduleMicrotask(() {
      // We need to re-check onError because it might have changed during the
      // asynchronous gap.
      if (onError != null) {
        onError(error);
      }
    });
  }

  @override
  String toString() => 'SocketReader($_socket)';

  void _handleWaitComplete(int status, int pending) {
    assert(isBound);
    if (status != ZX.OK) {
      close();
      _errorSoon(SocketReaderError(
          'Wait completed with status ${getStringForStatus(status)} ($status)',
          null));
      return;
    }
    // TODO(abarth): Change this try/catch pattern now that we don't use
    // RawReceivePort any more.
    try {
      if ((pending & Socket.READABLE) != 0) {
        if (onReadable != null) {
          onReadable();
        }
        if (isBound) {
          _asyncWait();
        }
      } else if ((pending & Socket.PEER_CLOSED) != 0) {
        close();
        _errorSoon(null);
      }
      // ignore: avoid_catching_errors
    } on Error catch (_) {
      // An Error exception from the core libraries is probably a programming
      // error that can't be handled. We rethrow the error so that
      // FidlEventHandlers can't swallow it by mistake.
      rethrow;
      // ignore: avoid_catches_without_on_clauses
    } catch (e, s) {
      close();
      _errorSoon(SocketReaderError(e, s));
    }
  }
}
