// Copyright 2014 The Flutter 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 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:mockito/mockito.dart';

import '../src/common.dart';
import '../src/context.dart';

void main() {
  TestRunner createTestRunner() {
    // TODO(jacobr): make these tests run with `trackWidgetCreation: true` as
    // well as the default flags.
    return TestRunner(
      <FlutterDevice>[FlutterDevice(MockDevice(), trackWidgetCreation: false, buildMode: BuildMode.debug)],
    );
  }

  group('keyboard input handling', () {
    testUsingContext('single help character', () async {
      final TestRunner testRunner = createTestRunner();
      final TerminalHandler terminalHandler = TerminalHandler(testRunner);
      expect(testRunner.hasHelpBeenPrinted, false);
      await terminalHandler.processTerminalInput('h');
      expect(testRunner.hasHelpBeenPrinted, true);
    });

    testUsingContext('help character surrounded with newlines', () async {
      final TestRunner testRunner = createTestRunner();
      final TerminalHandler terminalHandler = TerminalHandler(testRunner);
      expect(testRunner.hasHelpBeenPrinted, false);
      await terminalHandler.processTerminalInput('\nh\n');
      expect(testRunner.hasHelpBeenPrinted, true);
    });
  });

  group('keycode verification, brought to you by the letter', () {
    MockResidentRunner mockResidentRunner;
    TerminalHandler terminalHandler;

    setUp(() {
      mockResidentRunner = MockResidentRunner();
      terminalHandler = TerminalHandler(mockResidentRunner);
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(true);
    });

    testUsingContext('a, can handle trailing newlines', () async {
      await terminalHandler.processTerminalInput('a\n');

      expect(terminalHandler.lastReceivedCommand, 'a');
    });

    testUsingContext('n, can handle trailing only newlines', () async {
      await terminalHandler.processTerminalInput('\n\n');

      expect(terminalHandler.lastReceivedCommand, '');
    });

    testUsingContext('a - debugToggleProfileWidgetBuilds with service protocol', () async {
      await terminalHandler.processTerminalInput('a');

      verify(mockResidentRunner.debugToggleProfileWidgetBuilds()).called(1);
    });

    testUsingContext('a - debugToggleProfileWidgetBuilds without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('a');

      verifyNever(mockResidentRunner.debugToggleProfileWidgetBuilds());
    });


    testUsingContext('a - debugToggleProfileWidgetBuilds', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(true);
      await terminalHandler.processTerminalInput('a');

      verify(mockResidentRunner.debugToggleProfileWidgetBuilds()).called(1);
    });

    testUsingContext('d,D - detach', () async {
      await terminalHandler.processTerminalInput('d');
      await terminalHandler.processTerminalInput('D');

      verify(mockResidentRunner.detach()).called(2);
    });

    testUsingContext('h,H,? - printHelp', () async {
      await terminalHandler.processTerminalInput('h');
      await terminalHandler.processTerminalInput('H');
      await terminalHandler.processTerminalInput('?');

      verify(mockResidentRunner.printHelp(details: true)).called(3);
    });

    testUsingContext('i, I - debugToggleWidgetInspector with service protocol', () async {
      await terminalHandler.processTerminalInput('i');
      await terminalHandler.processTerminalInput('I');

      verify(mockResidentRunner.debugToggleWidgetInspector()).called(2);
    });

    testUsingContext('i, I - debugToggleWidgetInspector without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('i');
      await terminalHandler.processTerminalInput('I');

      verifyNever(mockResidentRunner.debugToggleWidgetInspector());
    });

    testUsingContext('l - list flutter views', () async {
      final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      when(mockResidentRunner.flutterDevices).thenReturn(<FlutterDevice>[mockFlutterDevice]);
      when(mockFlutterDevice.views).thenReturn(<FlutterView>[]);

      await terminalHandler.processTerminalInput('l');

      expect(testLogger.statusText, contains('Connected views:\n'));
    });

    testUsingContext('L - debugDumpLayerTree with service protocol', () async {
      await terminalHandler.processTerminalInput('L');

      verify(mockResidentRunner.debugDumpLayerTree()).called(1);
    });

    testUsingContext('L - debugDumpLayerTree without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('L');

      verifyNever(mockResidentRunner.debugDumpLayerTree());
    });

    testUsingContext('o,O - debugTogglePlatform with service protocol and debug mode', () async {
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('o');
      await terminalHandler.processTerminalInput('O');

      verify(mockResidentRunner.debugTogglePlatform()).called(2);
    });

    testUsingContext('o,O - debugTogglePlatform without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('o');
      await terminalHandler.processTerminalInput('O');

      verifyNever(mockResidentRunner.debugTogglePlatform());
    });

    testUsingContext('p - debugToggleDebugPaintSizeEnabled with service protocol and debug mode', () async {
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('p');

      verify(mockResidentRunner.debugToggleDebugPaintSizeEnabled()).called(1);
    });

    testUsingContext('p - debugTogglePlatform without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('p');

      verifyNever(mockResidentRunner.debugToggleDebugPaintSizeEnabled());
    });

    testUsingContext('p - debugToggleDebugPaintSizeEnabled with service protocol and debug mode', () async {
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('p');

      verify(mockResidentRunner.debugToggleDebugPaintSizeEnabled()).called(1);
    });

    testUsingContext('p - debugTogglePlatform without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      await terminalHandler.processTerminalInput('p');

      verifyNever(mockResidentRunner.debugToggleDebugPaintSizeEnabled());
    });

    testUsingContext('P - debugTogglePerformanceOverlayOverride with service protocol', () async {
      await terminalHandler.processTerminalInput('P');

      verify(mockResidentRunner.debugTogglePerformanceOverlayOverride()).called(1);
    });

    testUsingContext('P - debugTogglePerformanceOverlayOverride without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('P');

      verifyNever(mockResidentRunner.debugTogglePerformanceOverlayOverride());
    });

    testUsingContext('q,Q - exit', () async {
      await terminalHandler.processTerminalInput('q');
      await terminalHandler.processTerminalInput('Q');

      verify(mockResidentRunner.exit()).called(2);
    });

    testUsingContext('s - screenshot', () async {
      final MockDevice mockDevice = MockDevice();
      final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
      when(mockResidentRunner.isRunningDebug).thenReturn(true);
      when(mockResidentRunner.flutterDevices).thenReturn(<FlutterDevice>[mockFlutterDevice]);
      when(mockFlutterDevice.device).thenReturn(mockDevice);
      when(mockDevice.supportsScreenshot).thenReturn(true);

      await terminalHandler.processTerminalInput('s');

      verify(mockResidentRunner.screenshot(mockFlutterDevice)).called(1);
    });

    testUsingContext('r - hotReload supported and succeeds', () async {
      when(mockResidentRunner.canHotReload).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: false))
          .thenAnswer((Invocation invocation) async {
            return OperationResult(0, '');
          });
      await terminalHandler.processTerminalInput('r');

      verify(mockResidentRunner.restart(fullRestart: false)).called(1);
    });

    testUsingContext('r - hotReload supported and fails', () async {
      when(mockResidentRunner.canHotReload).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: false))
          .thenAnswer((Invocation invocation) async {
            return OperationResult(1, '');
          });
      await terminalHandler.processTerminalInput('r');

      verify(mockResidentRunner.restart(fullRestart: false)).called(1);

      expect(testLogger.statusText, contains('Try again after fixing the above error(s).'));
    });

    testUsingContext('r - hotReload supported and fails fatally', () async {
      when(mockResidentRunner.canHotReload).thenReturn(true);
      when(mockResidentRunner.hotMode).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: false))
        .thenAnswer((Invocation invocation) async {
          return OperationResult(1, 'fail', fatal: true);
        });
      expect(terminalHandler.processTerminalInput('r'), throwsA(isInstanceOf<ToolExit>()));
    });

    testUsingContext('r - hotReload unsupported', () async {
      when(mockResidentRunner.canHotReload).thenReturn(false);
      await terminalHandler.processTerminalInput('r');

      verifyNever(mockResidentRunner.restart(fullRestart: false));
    });

    testUsingContext('R - hotRestart supported and succeeds', () async {
      when(mockResidentRunner.canHotRestart).thenReturn(true);
      when(mockResidentRunner.hotMode).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: true))
        .thenAnswer((Invocation invocation) async {
          return OperationResult(0, '');
        });
      await terminalHandler.processTerminalInput('R');

      verify(mockResidentRunner.restart(fullRestart: true)).called(1);
    });

    testUsingContext('R - hotRestart supported and fails', () async {
      when(mockResidentRunner.canHotRestart).thenReturn(true);
      when(mockResidentRunner.hotMode).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: true))
        .thenAnswer((Invocation invocation) async {
          return OperationResult(1, 'fail');
        });
      await terminalHandler.processTerminalInput('R');

      verify(mockResidentRunner.restart(fullRestart: true)).called(1);

      expect(testLogger.statusText, contains('Try again after fixing the above error(s).'));
    });

    testUsingContext('R - hotRestart supported and fails fatally', () async {
      when(mockResidentRunner.canHotRestart).thenReturn(true);
      when(mockResidentRunner.hotMode).thenReturn(true);
      when(mockResidentRunner.restart(fullRestart: true))
        .thenAnswer((Invocation invocation) async {
          return OperationResult(1, 'fail', fatal: true);
        });
      expect(() => terminalHandler.processTerminalInput('R'), throwsA(isInstanceOf<ToolExit>()));
    });

    testUsingContext('R - hot restart unsupported', () async {
      when(mockResidentRunner.canHotRestart).thenReturn(false);
      await terminalHandler.processTerminalInput('R');

      verifyNever(mockResidentRunner.restart(fullRestart: true));
    });

    testUsingContext('S - debugDumpSemanticsTreeInTraversalOrder with service protocol', () async {
      await terminalHandler.processTerminalInput('S');

      verify(mockResidentRunner.debugDumpSemanticsTreeInTraversalOrder()).called(1);
    });

    testUsingContext('S - debugDumpSemanticsTreeInTraversalOrder without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('S');

      verifyNever(mockResidentRunner.debugDumpSemanticsTreeInTraversalOrder());
    });

    testUsingContext('t,T - debugDumpRenderTree with service protocol', () async {
      await terminalHandler.processTerminalInput('t');
      await terminalHandler.processTerminalInput('T');

      verify(mockResidentRunner.debugDumpRenderTree()).called(2);
    });

    testUsingContext('t,T - debugDumpSemanticsTreeInTraversalOrder without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('t');
      await terminalHandler.processTerminalInput('T');

      verifyNever(mockResidentRunner.debugDumpRenderTree());
    });

    testUsingContext('U - debugDumpRenderTree with service protocol', () async {
      await terminalHandler.processTerminalInput('U');

      verify(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder()).called(1);
    });

    testUsingContext('U - debugDumpSemanticsTreeInTraversalOrder without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('U');

      verifyNever(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder());
    });

    testUsingContext('w,W - debugDumpApp with service protocol', () async {
      await terminalHandler.processTerminalInput('w');
      await terminalHandler.processTerminalInput('W');

      verify(mockResidentRunner.debugDumpApp()).called(2);
    });

    testUsingContext('w,W - debugDumpApp without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('w');
      await terminalHandler.processTerminalInput('W');

      verifyNever(mockResidentRunner.debugDumpApp());
    });

    testUsingContext('z,Z - debugToggleDebugCheckElevationsEnabled with service protocol', () async {
      await terminalHandler.processTerminalInput('z');
      await terminalHandler.processTerminalInput('Z');

      verify(mockResidentRunner.debugToggleDebugCheckElevationsEnabled()).called(2);
    });

    testUsingContext('z,Z - debugToggleDebugCheckElevationsEnabled without service protocol', () async {
      when(mockResidentRunner.supportsServiceProtocol).thenReturn(false);
      await terminalHandler.processTerminalInput('z');
      await terminalHandler.processTerminalInput('Z');

      // This should probably be disable when the service protocol is not enabled.
      verify(mockResidentRunner.debugToggleDebugCheckElevationsEnabled()).called(2);
    });
  });
}

class MockDevice extends Mock implements Device {
  MockDevice() {
    when(isSupported()).thenReturn(true);
  }
}

class MockResidentRunner extends Mock implements ResidentRunner {}

class MockFlutterDevice extends Mock implements FlutterDevice {}

class TestRunner extends ResidentRunner {
  TestRunner(List<FlutterDevice> devices)
    : super(devices);

  bool hasHelpBeenPrinted = false;
  String receivedCommand;

  @override
  Future<void> cleanupAfterSignal() async { }

  @override
  Future<void> cleanupAtFinish() async { }

  @override
  void printHelp({ bool details }) {
    hasHelpBeenPrinted = true;
  }

  @override
  Future<int> run({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    String route,
  }) async => null;

  @override
  Future<int> attach({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
  }) async => null;
}
