// 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 'dart:io';

import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:process/process.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';

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

void main() {
  Directory tempDir;
  final ProjectWithEarlyError _project = ProjectWithEarlyError();
  const String _exceptionStart = '══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞══════════════════';
  FlutterRunTestDriver _flutter;

  setUp(() async {
    tempDir = createResolvedTempDirectorySync('run_test.');
    await _project.setUpIn(tempDir);
    _flutter = FlutterRunTestDriver(tempDir);
  });

  tearDown(() async {
    tryToDelete(tempDir);
  });

  test('flutter run in non-machine mode reports an early error in an application', () async {
    final String flutterBin = globals.fs.path.join(
      getFlutterRoot(),
      'bin',
      'flutter',
    );

    final StringBuffer stdout = StringBuffer();

    final Process process = await const LocalProcessManager().start(<String>[
      flutterBin,
      'run',
      '--disable-service-auth-codes',
      '--show-test-device',
      '-dflutter-tester',
      '--start-paused',
      '--dart-define=flutter.inspector.structuredErrors=true',
    ], workingDirectory: tempDir.path);

    transformToLines(process.stdout).listen((String line) async {
      stdout.writeln(line);

      if (line.startsWith('An Observatory debugger')) {
        final RegExp exp = RegExp(r'http://127.0.0.1:(\d+)/');
        final RegExpMatch match = exp.firstMatch(line);
        final String port = match.group(1);
        if (port != null) {
          final VmService vmService =
              await vmServiceConnectUri('ws://localhost:$port/ws');
          final VM vm = await vmService.getVM();
          for (final IsolateRef isolate in vm.isolates) {
            await vmService.resume(isolate.id);
          }
        }
      }

      if (line.startsWith('Another exception was thrown')) {
        process.kill();
      }
    });

    await process.exitCode;

    expect(stdout.toString(), contains(_exceptionStart));
  });

  test('flutter run in machine mode does not print an error', () async {
    final StringBuffer stdout = StringBuffer();

    await _flutter.run(
      startPaused: true,
      withDebugger: true,
      structuredErrors: true,
    );
    await _flutter.resume();

    final Completer<void> completer = Completer<void>();

    await Future<void>(() async {
      _flutter.stdout.listen((String line) {
        stdout.writeln(line);
      });
      await completer.future;
    }).timeout(const Duration(seconds: 5), onTimeout: () {
      // We don't expect to see any output but want to write to stdout anyway.
      completer.complete();
    });
    await _flutter.stop();

    expect(stdout.toString(), isNot(contains(_exceptionStart)));
  });

  test('flutter run for web reports an early error in an application', () async {
    final StringBuffer stdout = StringBuffer();

    await _flutter.run(
      startPaused: true,
      withDebugger: true,
      structuredErrors: true,
      chrome: true,
      machine: false,
    );
    await _flutter.resume();
    final Completer<void> completer = Completer<void>();
    bool lineFound = false;

    await Future<void>(() async {
      _flutter.stdout.listen((String line) {
        stdout.writeln(line);
        if (line.startsWith('Another exception was thrown') && !lineFound) {
          lineFound = true;
          completer.complete();
        }
      });
      await completer.future;
    }).timeout(const Duration(seconds: 15), onTimeout: () {
      // Complete anyway in case we don't see the 'Another exception' line.
      completer.complete();
    });

    expect(stdout.toString(), contains(_exceptionStart));
    await _flutter.stop();
  }, skip: 'Running in cirrus environment causes premature exit');
}
