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

import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:zircon/zircon.dart';

/// Helper method to turn a [String] into a [ByteData] containing the
/// text of the string encoded as UTF-8.
ByteData utf8Bytes(final String text) {
  return new ByteData.view(new Uint8List.fromList(utf8.encode(text)).buffer);
}

void main() {
  test('create channel', () {
    final HandlePairResult pair = System.channelCreate();
    expect(pair.status, equals(ZX.OK));
    expect(pair.first.isValid, isTrue);
    expect(pair.second.isValid, isTrue);
  });

  test('close channel', () {
    final HandlePairResult pair = System.channelCreate();
    expect(pair.first.close(), equals(0));
    expect(pair.first.isValid, isFalse);
    expect(pair.second.isValid, isTrue);
    expect(System.channelWrite(pair.first, new ByteData(1), <Handle>[]),
        equals(ZX.ERR_BAD_HANDLE));
    expect(System.channelWrite(pair.second, new ByteData(1), <Handle>[]),
        equals(ZX.ERR_PEER_CLOSED));
  });

  test('channel bytes', () {
    final HandlePairResult pair = System.channelCreate();

    // When no data is available, ZX.ERR_SHOULD_WAIT is returned.
    expect(System.channelQueryAndRead(pair.second).status,
        equals(ZX.ERR_SHOULD_WAIT));

    // Write bytes.
    final ByteData data = utf8Bytes('Hello, world');
    final int status = System.channelWrite(pair.first, data, <Handle>[]);
    expect(status, equals(ZX.OK));

    // Read bytes.
    final ReadResult readResult = System.channelQueryAndRead(pair.second);
    expect(readResult.status, equals(ZX.OK));
    expect(readResult.numBytes, equals(data.lengthInBytes));
    expect(readResult.bytes.lengthInBytes, equals(data.lengthInBytes));
    expect(readResult.bytesAsUTF8String(), equals('Hello, world'));
    expect(readResult.handles.length, equals(0));
  });

  test('channel handles', () {
    final HandlePairResult pair = System.channelCreate();
    final ByteData data = utf8Bytes('');
    final HandlePairResult eventPair = System.eventpairCreate();
    final int status =
        System.channelWrite(pair.first, data, <Handle>[eventPair.first]);
    expect(status, equals(ZX.OK));
    expect(eventPair.first.isValid, isFalse);

    final ReadResult readResult = System.channelQueryAndRead(pair.second);
    expect(readResult.status, equals(ZX.OK));
    expect(readResult.numBytes, equals(0));
    expect(readResult.bytes.lengthInBytes, equals(0));
    expect(readResult.bytesAsUTF8String(), equals(''));
    expect(readResult.handles.length, equals(1));
    expect(readResult.handles[0].isValid, isTrue);
  });

  test('async wait channel read', () async {
    final HandlePairResult pair = System.channelCreate();
    final Completer<List<int>> completer = new Completer<List<int>>();
    pair.first.asyncWait(ZX.CHANNEL_READABLE, (int status, int pending) {
      completer.complete(<int>[status, pending]);
    });

    expect(completer.isCompleted, isFalse);

    System.channelWrite(pair.second, utf8Bytes('Hi'), <Handle>[]);

    final List<int> result = await completer.future;
    expect(result[0], equals(ZX.OK)); // status
    expect(result[1] & ZX.CHANNEL_READABLE,
        equals(ZX.CHANNEL_READABLE)); // pending
  });

  test('async wait channel closed', () async {
    final HandlePairResult pair = System.channelCreate();
    final Completer<int> completer = new Completer<int>();
    pair.first.asyncWait(ZX.CHANNEL_PEER_CLOSED, (int status, int pending) {
      completer.complete(status);
    });

    expect(completer.isCompleted, isFalse);

    pair.second.close();

    final int status = await completer.future;
    expect(status, equals(ZX.OK));
  });
}
