// 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:file/file.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';

import '../src/common.dart';
import 'test_data/hot_reload_project.dart';
import 'test_driver.dart';
import 'test_utils.dart';

void main() {
  Directory tempDir;
  final HotReloadProject project = HotReloadProject();
  FlutterRunTestDriver flutter;

  setUp(() async {
    tempDir = createResolvedTempDirectorySync('hot_reload_test.');
    await project.setUpIn(tempDir);
    flutter = FlutterRunTestDriver(tempDir);
  });

  tearDown(() async {
    await flutter?.stop();
    tryToDelete(tempDir);
  });

  testWithoutContext('hot reload works without error', () async {
    await flutter.run();
    await flutter.hotReload();
  });

  testWithoutContext('multiple overlapping hot reload are debounced and queued', () async {
    await flutter.run();
    // Capture how many *real* hot reloads occur.
    int numReloads = 0;
    final StreamSubscription<void> subscription = flutter.stdout
        .map(parseFlutterResponse)
        .where(_isHotReloadCompletionEvent)
        .listen((_) => numReloads++);

    // To reduce tests flaking, override the debounce timer to something higher than
    // the default to ensure the hot reloads that are supposed to arrive within the
    // debounce period will even on slower CI machines.
    const int hotReloadDebounceOverrideMs = 250;
    const Duration delay = Duration(milliseconds: hotReloadDebounceOverrideMs * 2);

    Future<void> doReload([void _]) =>
        flutter.hotReload(debounce: true, debounceDurationOverrideMs: hotReloadDebounceOverrideMs);

    try {
      await Future.wait<void>(<Future<void>>[
        doReload(),
        doReload(),
        Future<void>.delayed(delay).then(doReload),
        Future<void>.delayed(delay).then(doReload),
      ]);

      // We should only get two reloads, as the first two will have been
      // merged together by the debounce, and the second two also.
      expect(numReloads, equals(2));
    } finally {
      await subscription.cancel();
    }
  });

  testWithoutContext('newly added code executes during hot reload', () async {
    final StringBuffer stdout = StringBuffer();
    final StreamSubscription<String> subscription = flutter.stdout.listen(stdout.writeln);
    await flutter.run();
    project.uncommentHotReloadPrint();
    try {
      await flutter.hotReload();
      expect(stdout.toString(), contains('(((((RELOAD WORKED)))))'));
    } finally {
      await subscription.cancel();
    }
  });

  testWithoutContext('fastReassemble behavior triggers hot reload behavior with evaluation of expression', () async {
    final Completer<void> tick1 = Completer<void>();
    final Completer<void> tick2 = Completer<void>();
    final Completer<void> tick3 = Completer<void>();
    final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
      if (line.contains('TICK 1')) {
        tick1.complete();
      }
      if (line.contains('TICK 2')) {
        tick2.complete();
      }
      if (line.contains('TICK 3')) {
        tick3.complete();
      }
    });
    await flutter.run(withDebugger: true);

    final int port = flutter.vmServicePort;
    final VmService vmService = await vmServiceConnectUri('ws://localhost:$port/ws');
    await tick1.future;
    try {
      // Since the single-widget reload feature is not yet implemented, manually
      // evaluate the expression for the reload.
      final Isolate isolate = await waitForExtension(vmService);
      final LibraryRef targetRef = isolate.libraries.firstWhere((LibraryRef libraryRef) {
        return libraryRef.uri == 'package:test/main.dart';
      });
      await vmService.evaluate(
        isolate.id,
        targetRef.id,
        '((){debugFastReassembleMethod=(Object x) => x is MyApp})()',
      );

      final Response fastReassemble1 = await vmService
        .callServiceExtension('ext.flutter.fastReassemble', isolateId: isolate.id);

      // _extensionType indicates success.
      expect(fastReassemble1.type, '_extensionType');
      await tick2.future;

      // verify evaluation did not produce invalidat type by checking with dart:core
      // type.
      await vmService.evaluate(
        isolate.id,
        targetRef.id,
        '((){debugFastReassembleMethod=(Object x) => x is bool})()',
      );

      final Response fastReassemble2 = await vmService
        .callServiceExtension('ext.flutter.fastReassemble', isolateId: isolate.id);

      // _extensionType indicates success.
      expect(fastReassemble2.type, '_extensionType');
      unawaited(tick3.future.whenComplete(() {
        fail('Should not complete');
      }));

      // Invocation without evaluation leads to runtime error.
      expect(vmService
        .callServiceExtension('ext.flutter.fastReassemble', isolateId: isolate.id),
        throwsA(isA<Exception>())
      );
    } finally {
      await subscription.cancel();
    }
  });

  testWithoutContext('hot restart works without error', () async {
    await flutter.run();
    await flutter.hotRestart();
  });

  testWithoutContext('breakpoints are hit after hot reload', () async {
    Isolate isolate;
    final Completer<void> sawTick1 = Completer<void>();
    final Completer<void> sawDebuggerPausedMessage = Completer<void>();
    final StreamSubscription<String> subscription = flutter.stdout.listen(
      (String line) {
        if (line.contains('((((TICK 1))))')) {
          expect(sawTick1.isCompleted, isFalse);
          sawTick1.complete();
        }
        if (line.contains('The application is paused in the debugger on a breakpoint.')) {
          expect(sawDebuggerPausedMessage.isCompleted, isFalse);
          sawDebuggerPausedMessage.complete();
        }
      },
    );
    await flutter.run(withDebugger: true, startPaused: true);
    await flutter.resume(); // we start paused so we can set up our TICK 1 listener before the app starts
    unawaited(sawTick1.future.timeout(
      const Duration(seconds: 5),
      onTimeout: () { print('The test app is taking longer than expected to print its synchronization line...'); },
    ));
    await sawTick1.future; // after this, app is in steady state
    await flutter.addBreakpoint(
      project.scheduledBreakpointUri,
      project.scheduledBreakpointLine,
    );
    await Future<void>.delayed(const Duration(seconds: 2));
    await flutter.hotReload(); // reload triggers code which eventually hits the breakpoint
    isolate = await flutter.waitForPause();
    expect(isolate.pauseEvent.kind, equals(EventKind.kPauseBreakpoint));
    await flutter.resume();
    await flutter.addBreakpoint(
      project.buildBreakpointUri,
      project.buildBreakpointLine,
    );
    bool reloaded = false;
    final Future<void> reloadFuture = flutter.hotReload().then((void value) { reloaded = true; });
    print('waiting for pause...');
    isolate = await flutter.waitForPause();
    expect(isolate.pauseEvent.kind, equals(EventKind.kPauseBreakpoint));
    print('waiting for debugger message...');
    await sawDebuggerPausedMessage.future;
    expect(reloaded, isFalse);
    print('waiting for resume...');
    await flutter.resume();
    print('waiting for reload future...');
    await reloadFuture;
    expect(reloaded, isTrue);
    reloaded = false;
    print('subscription cancel...');
    await subscription.cancel();
  });

  testWithoutContext("hot reload doesn't reassemble if paused", () async {
    final Completer<void> sawTick1 = Completer<void>();
    final Completer<void> sawDebuggerPausedMessage1 = Completer<void>();
    final Completer<void> sawDebuggerPausedMessage2 = Completer<void>();
    final StreamSubscription<String> subscription = flutter.stdout.listen(
      (String line) {
        print('[LOG]:"$line"');
        if (line.contains('(((TICK 1)))')) {
          expect(sawTick1.isCompleted, isFalse);
          sawTick1.complete();
        }
        if (line.contains('The application is paused in the debugger on a breakpoint.')) {
          expect(sawDebuggerPausedMessage1.isCompleted, isFalse);
          sawDebuggerPausedMessage1.complete();
        }
        if (line.contains('The application is paused in the debugger on a breakpoint; interface might not update.')) {
          expect(sawDebuggerPausedMessage2.isCompleted, isFalse);
          sawDebuggerPausedMessage2.complete();
        }
      },
    );
    await flutter.run(withDebugger: true);
    await Future<void>.delayed(const Duration(seconds: 1));
    await sawTick1.future;
    await flutter.addBreakpoint(
      project.buildBreakpointUri,
      project.buildBreakpointLine,
    );
    bool reloaded = false;
    await Future<void>.delayed(const Duration(seconds: 1));
    final Future<void> reloadFuture = flutter.hotReload().then((void value) { reloaded = true; });
    final Isolate isolate = await flutter.waitForPause();
    expect(isolate.pauseEvent.kind, equals(EventKind.kPauseBreakpoint));
    expect(reloaded, isFalse);
    await sawDebuggerPausedMessage1.future; // this is the one where it say "uh, you broke into the debugger while reloading"
    await reloadFuture; // this is the one where it times out because you're in the debugger
    expect(reloaded, isTrue);
    await flutter.hotReload(); // now we're already paused
    await sawDebuggerPausedMessage2.future; // so we just get told that nothing is going to happen
    await flutter.resume();
    await subscription.cancel();
  });
}

bool _isHotReloadCompletionEvent(Map<String, dynamic> event) {
  return event != null &&
      event['event'] == 'app.progress' &&
      event['params'] != null &&
      event['params']['progressId'] == 'hot.reload' &&
      event['params']['finished'] == true;
}
