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

import 'dart:async';
import 'dart:convert' show ascii;
import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_ui_input/fidl_async.dart'
    show KeyboardEvent, KeyboardEventPhase, kModifierLeftAlt;
import 'package:fidl_fuchsia_ui_policy/fidl_async.dart'
    show
        KeyboardCaptureListenerHack,
        KeyboardCaptureListenerHackProxy,
        Presentation;

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:lib.story_shell/common.dart';

/// Test keyevents are triggering callbacks
/// This needs to run on Fuchsia because we are using real InterfaceHandles
class MockPresentation extends Mock implements Presentation {
  KeyboardEvent _eventToCapture;
  final KeyboardCaptureListenerHackProxy _proxy =
      KeyboardCaptureListenerHackProxy();
  @override
  Future<void> captureKeyboardEventHack(KeyboardEvent eventToCapture,
      InterfaceHandle<KeyboardCaptureListenerHack> listener) async {
    _eventToCapture = eventToCapture;
    _proxy.ctrl.bind(listener);
  }

  void triggerEvent() {
    _proxy.onEvent(_eventToCapture);
  }
}

// Test class for capturing if callbacks are being called correctly
class CallbackTest {
  bool _called = false;

  /// Has this been called.
  bool get called => _called;

  /// We will give this as the callback to check if the event listener is
  /// correctly calling on events
  void call() {
    _called = true;
  }
}

void main() {
  KeyboardEvent _upperCaseQ;
  KeyboardEvent _lAltT;

  setUp(() {
    _lAltT = KeyboardEvent(
        codePoint: ascii.encode('T')[0],
        hidUsage: 0,
        eventTime: 0,
        deviceId: 0,
        modifiers: kModifierLeftAlt,
        phase: KeyboardEventPhase.pressed);

    _upperCaseQ = KeyboardEvent(
        codePoint: ascii.encode('Q')[0],
        hidUsage: 0,
        eventTime: 0,
        deviceId: 0,
        modifiers: 0,
        phase: KeyboardEventPhase.pressed);
  });

  /// Test registering and unregistering keyevent/callback pairs
  group('Single event registered:', () {
    test('registerKeyboardEventCallback registers the pair with KeyListener',
        () {
      KeyListener keyListener = KeyListener();
      void callbackA() => null;
      keyListener.registerKeyboardEventCallback(
          event: _upperCaseQ, callback: callbackA);
      expect(keyListener.registeredEvents[_upperCaseQ], contains(callbackA));
    });
    test('event is triggered by corresponding KeyEvent:', () async {
      KeyListener keyListener = KeyListener();
      CallbackTest test = CallbackTest();
      MockPresentation mockPresentation = MockPresentation();
      keyListener.registerKeyboardEventCallback(
          event: _upperCaseQ, callback: test.call);
      expect(keyListener.registeredEvents[_upperCaseQ], contains(test.call));
      // This will automatically call captureKeyboardEventHack() on all
      // registered events, wrapping the listener in an InterfaceHandle.
      // The mock class has overridden this.
      keyListener.listen(mockPresentation);
      // Trigger the registered event, which should call the callback
      mockPresentation.triggerEvent();
      // give the call time to propagate
      Future sleep1() {
        return new Future.delayed(const Duration(seconds: 1), () {});
      }

      await sleep1();
      expect(test.called, true);
    });
  });

  group('Multiple events registered:', () {
    test('registerKeyboardEventCallback registers two pairs with KeyListener',
        () {
      KeyListener keyListener = KeyListener();
      void callbackA() => 'A';
      keyListener.registerKeyboardEventCallback(
          event: _upperCaseQ, callback: callbackA);
      void callbackB() => 'B';
      keyListener.registerKeyboardEventCallback(
          event: _lAltT, callback: callbackB);
      expect(keyListener.registeredEvents[_upperCaseQ], contains(callbackA));
      expect(keyListener.registeredEvents[_lAltT], contains(callbackB));
    });
  });
}
