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

// @dart = 2.8

// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=20210723"
@Tags(<String>['no-shuffle'])

import 'dart:async';

import 'package:args/command_runner.dart';
import 'package:fake_async/fake_async.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_studio_validator.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/doctor.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:flutter_tools/src/vscode/vscode.dart';
import 'package:flutter_tools/src/vscode/vscode_validator.dart';
import 'package:flutter_tools/src/web/workflow.dart';
import 'package:test/fake.dart';

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

final Platform macPlatform = FakePlatform(
  operatingSystem: 'macos',
  environment: <String, String>{'HOME': '/foo/bar'}
);

void main() {
  FakeFlutterVersion flutterVersion;
  BufferLogger logger;
  FakeProcessManager fakeProcessManager;

  setUp(() {
    flutterVersion = FakeFlutterVersion();
    logger = BufferLogger.test();
    fakeProcessManager = FakeProcessManager.empty();
  });

  testWithoutContext('ValidationMessage equality and hashCode includes contextUrl', () {
    const ValidationMessage messageA = ValidationMessage('ab', contextUrl: 'a');
    const ValidationMessage messageB = ValidationMessage('ab', contextUrl: 'b');

    expect(messageB, isNot(messageA));
    expect(messageB.hashCode, isNot(messageA.hashCode));
    expect(messageA, isNot(messageB));
    expect(messageA.hashCode, isNot(messageB.hashCode));
  });

  group('doctor', () {
    testUsingContext('vs code validator when both installed', () async {
      final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension.validate();
      expect(result.type, ValidationType.installed);
      expect(result.statusInfo, 'version 1.2.3');
      expect(result.messages, hasLength(2));

      ValidationMessage message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('VS Code '));
      expect(message.message, 'VS Code at ${VsCodeValidatorTestTargets.validInstall}');

      message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('Flutter '));
      expect(message.message, 'Flutter extension version 4.5.6');
      expect(message.isError, isFalse);
    });

    testUsingContext('No IDE Validator includes expected installation messages', () async {
      final ValidationResult result = await NoIdeValidator().validate();
      expect(result.type, ValidationType.notAvailable);

      expect(
        result.messages.map((ValidationMessage vm) => vm.message),
        UserMessages().noIdeInstallationInfo,
      );
    });

    testUsingContext('vs code validator when 64bit installed', () async {
      expect(VsCodeValidatorTestTargets.installedWithExtension64bit.title, 'VS Code, 64-bit edition');
      final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension64bit.validate();
      expect(result.type, ValidationType.installed);
      expect(result.statusInfo, 'version 1.2.3');
      expect(result.messages, hasLength(2));

      ValidationMessage message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('VS Code '));
      expect(message.message, 'VS Code at ${VsCodeValidatorTestTargets.validInstall}');

      message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('Flutter '));
      expect(message.message, 'Flutter extension version 4.5.6');
    });

    testUsingContext('vs code validator when extension missing', () async {
      final ValidationResult result = await VsCodeValidatorTestTargets.installedWithoutExtension.validate();
      expect(result.type, ValidationType.installed);
      expect(result.statusInfo, 'version 1.2.3');
      expect(result.messages, hasLength(2));

      ValidationMessage message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('VS Code '));
      expect(message.message, 'VS Code at ${VsCodeValidatorTestTargets.validInstall}');

      message = result.messages
          .firstWhere((ValidationMessage m) => m.message.startsWith('Flutter '));
      expect(message.message, startsWith('Flutter extension can be installed from'));
      expect(message.contextUrl, 'https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter');
      expect(message.isError, false);
    });

    group('device validator', () {
      testWithoutContext('no devices', () async {
        final FakeDeviceManager deviceManager = FakeDeviceManager();
        final DeviceValidator deviceValidator = DeviceValidator(
          deviceManager: deviceManager,
          userMessages: UserMessages(),
        );
        final ValidationResult result = await deviceValidator.validate();
        expect(result.type, ValidationType.notAvailable);
        expect(result.messages, const <ValidationMessage>[
          ValidationMessage.hint('No devices available'),
        ]);
        expect(result.statusInfo, isNull);
      });

      testWithoutContext('diagnostic message', () async {
        final FakeDeviceManager deviceManager = FakeDeviceManager()
          ..diagnostics = <String>['Device locked'];

        final DeviceValidator deviceValidator = DeviceValidator(
          deviceManager: deviceManager,
          userMessages: UserMessages(),
        );
        final ValidationResult result = await deviceValidator.validate();
        expect(result.type, ValidationType.notAvailable);
        expect(result.messages, const <ValidationMessage>[
          ValidationMessage.hint('Device locked'),
        ]);
        expect(result.statusInfo, isNull);
      });

      testWithoutContext('diagnostic message and devices', () async {
        final FakeDevice device = FakeDevice();
        final FakeDeviceManager deviceManager = FakeDeviceManager()
          ..devices = <Device>[device]
          ..diagnostics = <String>['Device locked'];

        final DeviceValidator deviceValidator = DeviceValidator(
          deviceManager: deviceManager,
          userMessages: UserMessages(),
        );
        final ValidationResult result = await deviceValidator.validate();
        expect(result.type, ValidationType.installed);
        expect(result.messages, const <ValidationMessage>[
          ValidationMessage('name (mobile) • device-id • android • 1.2.3'),
          ValidationMessage.hint('Device locked'),
        ]);
        expect(result.statusInfo, '1 available');
      });
    });
  });

  group('doctor with overridden validators', () {
    testUsingContext('validate non-verbose output format for run without issues', () async {
      final Doctor doctor = Doctor(logger: logger);
      expect(await doctor.diagnose(verbose: false), isTrue);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[✓] Another Passing Validator (with statusInfo)\n'
              '[✓] Providing validators is fun (with statusInfo)\n'
              '\n'
              '• No issues found!\n'
      ));
    }, overrides: <Type, Generator>{
      DoctorValidatorsProvider: () => FakeDoctorValidatorsProvider(),
    });
  });

  group('doctor usage params', () {
    TestUsage testUsage;

    setUp(() {
      testUsage = TestUsage();
    });

    testUsingContext('contains installed', () async {
      final Doctor doctor = Doctor(logger: logger);
      await doctor.diagnose(verbose: false);

      expect(testUsage.events.length, 3);
      expect(testUsage.events, contains(
        const TestUsageEvent(
          'doctor-result',
          'PassingValidator',
          label: 'installed',
        ),
      ));
    }, overrides: <Type, Generator>{
      DoctorValidatorsProvider: () => FakeDoctorValidatorsProvider(),
      Usage: () => testUsage,
    });

    testUsingContext('contains installed and partial', () async {
      await FakePassingDoctor(logger).diagnose(verbose: false);

      expect(testUsage.events, unorderedEquals(<TestUsageEvent>[
        const TestUsageEvent(
          'doctor-result',
          'PassingValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PassingValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PartialValidatorWithHintsOnly',
          label: 'partial',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PartialValidatorWithErrors',
          label: 'partial',
        ),
      ]));
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });

    testUsingContext('contains installed, missing and partial', () async {
      await FakeDoctor(logger).diagnose(verbose: false);

      expect(testUsage.events, unorderedEquals(<TestUsageEvent>[
        const TestUsageEvent(
          'doctor-result',
          'PassingValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'MissingValidator',
          label: 'missing',
        ),
        const TestUsageEvent(
          'doctor-result',
          'NotAvailableValidator',
          label: 'notAvailable',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PartialValidatorWithHintsOnly',
          label: 'partial',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PartialValidatorWithErrors',
          label: 'partial',
        ),
      ]));
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });

    testUsingContext('events for grouped validators are properly decomposed', () async {
      await FakeGroupedDoctor(logger).diagnose(verbose: false);

      expect(testUsage.events, unorderedEquals(<TestUsageEvent>[
        const TestUsageEvent(
          'doctor-result',
          'PassingGroupedValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PassingGroupedValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'PassingGroupedValidator',
          label: 'installed',
        ),
        const TestUsageEvent(
          'doctor-result',
          'MissingGroupedValidator',
          label: 'missing',
        ),
      ]));
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });

    testUsingContext('sending events can be skipped', () async {
      await FakePassingDoctor(logger).diagnose(verbose: false, sendEvent: false);

      expect(testUsage.events, isEmpty);
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });
  });

  group('doctor with fake validators', () {
    testUsingContext('validate non-verbose output format for run without issues', () async {
      expect(await FakeQuietDoctor(logger).diagnose(verbose: false), isTrue);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[✓] Another Passing Validator (with statusInfo)\n'
              '[✓] Validators are fun (with statusInfo)\n'
              '[✓] Four score and seven validators ago (with statusInfo)\n'
              '\n'
              '• No issues found!\n'
      ));
    });

    testUsingContext('validate non-verbose output format for run with crash', () async {
      expect(await FakeCrashingDoctor(logger).diagnose(verbose: false), isFalse);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[✓] Another Passing Validator (with statusInfo)\n'
              '[☠] Crashing validator (the doctor check crashed)\n'
              '    ✗ Due to an error, the doctor check did not complete. If the error message below is not helpful, '
              'please let us know about this issue at https://github.com/flutter/flutter/issues.\n'
              '    ✗ Bad state: fatal error\n'
              '[✓] Validators are fun (with statusInfo)\n'
              '[✓] Four score and seven validators ago (with statusInfo)\n'
              '\n'
              '! Doctor found issues in 1 category.\n'
      ));
    });

    testUsingContext('validate verbose output format contains trace for run with crash', () async {
      expect(await FakeCrashingDoctor(logger).diagnose(), isFalse);
      expect(logger.statusText, contains('#0      CrashingValidator.validate'));
    });

    testUsingContext('validate tool exit when exceeding timeout', () async {
      FakeAsync().run<void>((FakeAsync time) {
        final Doctor doctor = FakeAsyncStuckDoctor(logger);
        doctor.diagnose(verbose: false);
        time.elapse(Doctor.doctorDuration + const Duration(seconds: 1));
        time.flushMicrotasks();
      });

      expect(logger.statusText, contains('Stuck validator that never completes exceeded maximum allowed duration of '));
    });

    testUsingContext('validate non-verbose output format for run with an async crash', () async {
      final Completer<void> completer = Completer<void>();
      await FakeAsync().run((FakeAsync time) {
        unawaited(FakeAsyncCrashingDoctor(time, logger).diagnose(verbose: false).then((bool r) {
          expect(r, isFalse);
          completer.complete(null);
        }));
        time.elapse(const Duration(seconds: 1));
        time.flushMicrotasks();
        return completer.future;
      });
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[✓] Another Passing Validator (with statusInfo)\n'
              '[☠] Async crashing validator (the doctor check crashed)\n'
              '    ✗ Due to an error, the doctor check did not complete. If the error message below is not helpful, '
              'please let us know about this issue at https://github.com/flutter/flutter/issues.\n'
              '    ✗ Bad state: fatal error\n'
              '[✓] Validators are fun (with statusInfo)\n'
              '[✓] Four score and seven validators ago (with statusInfo)\n'
              '\n'
              '! Doctor found issues in 1 category.\n'
      ));
    });


    testUsingContext('validate non-verbose output format when only one category fails', () async {
      expect(await FakeSinglePassingDoctor(logger).diagnose(verbose: false), isTrue);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[!] Partial Validator with only a Hint\n'
              '    ! There is a hint here\n'
              '\n'
              '! Doctor found issues in 1 category.\n'
      ));
    });

    testUsingContext('validate non-verbose output format for a passing run', () async {
      expect(await FakePassingDoctor(logger).diagnose(verbose: false), isTrue);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[!] Partial Validator with only a Hint\n'
              '    ! There is a hint here\n'
              '[!] Partial Validator with Errors\n'
              '    ✗ An error message indicating partial installation\n'
              '    ! Maybe a hint will help the user\n'
              '[✓] Another Passing Validator (with statusInfo)\n'
              '\n'
              '! Doctor found issues in 2 categories.\n'
      ));
    });

    testUsingContext('validate non-verbose output format', () async {
      expect(await FakeDoctor(logger).diagnose(verbose: false), isFalse);
      expect(logger.statusText, equals(
              'Doctor summary (to see all details, run flutter doctor -v):\n'
              '[✓] Passing Validator (with statusInfo)\n'
              '[✗] Missing Validator\n'
              '    ✗ A useful error message\n'
              '    ! A hint message\n'
              '[!] Not Available Validator\n'
              '    ✗ A useful error message\n'
              '    ! A hint message\n'
              '[!] Partial Validator with only a Hint\n'
              '    ! There is a hint here\n'
              '[!] Partial Validator with Errors\n'
              '    ✗ An error message indicating partial installation\n'
              '    ! Maybe a hint will help the user\n'
              '\n'
              '! Doctor found issues in 4 categories.\n'
      ));
    });

    testUsingContext('validate verbose output format', () async {
      expect(await FakeDoctor(logger).diagnose(), isFalse);
      expect(logger.statusText, equals(
              '[✓] Passing Validator (with statusInfo)\n'
              '    • A helpful message\n'
              '    • A second, somewhat longer helpful message\n'
              '\n'
              '[✗] Missing Validator\n'
              '    ✗ A useful error message\n'
              '    • A message that is not an error\n'
              '    ! A hint message\n'
              '\n'
              '[!] Not Available Validator\n'
              '    ✗ A useful error message\n'
              '    • A message that is not an error\n'
              '    ! A hint message\n'
              '\n'
              '[!] Partial Validator with only a Hint\n'
              '    ! There is a hint here\n'
              '    • But there is no error\n'
              '\n'
              '[!] Partial Validator with Errors\n'
              '    ✗ An error message indicating partial installation\n'
              '    ! Maybe a hint will help the user\n'
              '    • An extra message with some verbose details\n'
              '\n'
              '! Doctor found issues in 4 categories.\n'
      ));
    });

    testUsingContext('validate PII can be hidden', () async {
      expect(await FakePiiDoctor(logger).diagnose(showPii: false), isTrue);
      expect(logger.statusText, equals(
        '[✓] PII Validator\n'
        '    • Does not contain PII\n'
        '\n'
        '• No issues found!\n'
      ));
      logger.clear();
      // PII shown.
      expect(await FakePiiDoctor(logger).diagnose(), isTrue);
      expect(logger.statusText, equals(
          '[✓] PII Validator\n'
              '    • Contains PII path/to/username\n'
              '\n'
              '• No issues found!\n'
      ));
    });
  });

  group('doctor diagnosis wrapper', () {
    TestUsage testUsage;
    BufferLogger logger;

    setUp(() {
      testUsage = TestUsage();
      logger = BufferLogger.test();
    });

    testUsingContext('PII separated, events only sent once', () async {
      final Doctor fakeDoctor = FakePiiDoctor(logger);
      final DoctorText doctorText = DoctorText(logger, doctor: fakeDoctor);
      const String expectedPiiText = '[✓] PII Validator\n'
          '    • Contains PII path/to/username\n'
          '\n'
          '• No issues found!\n';
      const String expectedPiiStrippedText =
          '[✓] PII Validator\n'
          '    • Does not contain PII\n'
          '\n'
          '• No issues found!\n';

      // Run each multiple times to make sure the logger buffer is being cleared,
      // and that events are only sent once.
      expect(await doctorText.text, expectedPiiText);
      expect(await doctorText.text, expectedPiiText);

      expect(await doctorText.piiStrippedText, expectedPiiStrippedText);
      expect(await doctorText.piiStrippedText, expectedPiiStrippedText);

      // Only one event sent.
      expect(testUsage.events, <TestUsageEvent>[
        const TestUsageEvent(
          'doctor-result',
          'PiiValidator',
          label: 'installed',
        ),
      ]);
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });

    testUsingContext('without PII has same text and PII-stripped text', () async {
      final Doctor fakeDoctor = FakePassingDoctor(logger);
      final DoctorText doctorText = DoctorText(logger, doctor: fakeDoctor);
      final String piiText = await doctorText.text;
      expect(piiText, isNotEmpty);
      expect(piiText, await doctorText.piiStrippedText);
    }, overrides: <Type, Generator>{
      Usage: () => testUsage,
    });
  });

  testUsingContext('validate non-verbose output wrapping', () async {
    final BufferLogger wrapLogger = BufferLogger.test(
      outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 30),
    );
    expect(await FakeDoctor(wrapLogger).diagnose(verbose: false), isFalse);
    expect(wrapLogger.statusText, equals(
        'Doctor summary (to see all\n'
        'details, run flutter doctor\n'
        '-v):\n'
        '[✓] Passing Validator (with\n'
        '    statusInfo)\n'
        '[✗] Missing Validator\n'
        '    ✗ A useful error message\n'
        '    ! A hint message\n'
        '[!] Not Available Validator\n'
        '    ✗ A useful error message\n'
        '    ! A hint message\n'
        '[!] Partial Validator with\n'
        '    only a Hint\n'
        '    ! There is a hint here\n'
        '[!] Partial Validator with\n'
        '    Errors\n'
        '    ✗ An error message\n'
        '      indicating partial\n'
        '      installation\n'
        '    ! Maybe a hint will help\n'
        '      the user\n'
        '\n'
        '! Doctor found issues in 4\n'
        '  categories.\n'
    ));
  });

  testUsingContext('validate verbose output wrapping', () async {
    final BufferLogger wrapLogger = BufferLogger.test(
      outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 30),
    );
    expect(await FakeDoctor(wrapLogger).diagnose(), isFalse);
    expect(wrapLogger.statusText, equals(
        '[✓] Passing Validator (with\n'
        '    statusInfo)\n'
        '    • A helpful message\n'
        '    • A second, somewhat\n'
        '      longer helpful message\n'
        '\n'
        '[✗] Missing Validator\n'
        '    ✗ A useful error message\n'
        '    • A message that is not an\n'
        '      error\n'
        '    ! A hint message\n'
        '\n'
        '[!] Not Available Validator\n'
        '    ✗ A useful error message\n'
        '    • A message that is not an\n'
        '      error\n'
        '    ! A hint message\n'
        '\n'
        '[!] Partial Validator with\n'
        '    only a Hint\n'
        '    ! There is a hint here\n'
        '    • But there is no error\n'
        '\n'
        '[!] Partial Validator with\n'
        '    Errors\n'
        '    ✗ An error message\n'
        '      indicating partial\n'
        '      installation\n'
        '    ! Maybe a hint will help\n'
        '      the user\n'
        '    • An extra message with\n'
        '      some verbose details\n'
        '\n'
        '! Doctor found issues in 4\n'
        '  categories.\n'
    ));
  });

  group('doctor with grouped validators', () {
    testUsingContext('validate diagnose combines validator output', () async {
      expect(await FakeGroupedDoctor(logger).diagnose(), isTrue);
      expect(logger.statusText, equals(
              '[✓] Category 1\n'
              '    • A helpful message\n'
              '    • A helpful message\n'
              '\n'
              '[!] Category 2\n'
              '    • A helpful message\n'
              '    ✗ A useful error message\n'
              '\n'
              '! Doctor found issues in 1 category.\n'
      ));
    });

    testUsingContext('validate merging assigns statusInfo and title', () async {
      // There are two subvalidators. Only the second contains statusInfo.
      expect(await FakeGroupedDoctorWithStatus(logger).diagnose(), isTrue);
      expect(logger.statusText, equals(
              '[✓] First validator title (A status message)\n'
              '    • A helpful message\n'
              '    • A different message\n'
              '\n'
              '• No issues found!\n'
      ));
    });
  });

  group('grouped validator merging results', () {
    final PassingGroupedValidator installed = PassingGroupedValidator('Category');
    final PartialGroupedValidator partial = PartialGroupedValidator('Category');
    final MissingGroupedValidator missing = MissingGroupedValidator('Category');

    testUsingContext('validate installed + installed = installed', () async {
      expect(await FakeSmallGroupDoctor(logger, installed, installed).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[✓]'));
    });

    testUsingContext('validate installed + partial = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, installed, partial).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate installed + missing = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, installed, missing).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate partial + installed = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, partial, installed).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate partial + partial = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, partial, partial).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate partial + missing = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, partial, missing).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate missing + installed = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, missing, installed).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate missing + partial = partial', () async {
      expect(await FakeSmallGroupDoctor(logger, missing, partial).diagnose(), isTrue);
      expect(logger.statusText, startsWith('[!]'));
    });

    testUsingContext('validate missing + missing = missing', () async {
      expect(await FakeSmallGroupDoctor(logger, missing, missing).diagnose(), isFalse);
      expect(logger.statusText, startsWith('[✗]'));
    });
  });

  testUsingContext('WebWorkflow is a part of validator workflows if enabled', () async {
    expect(DoctorValidatorsProvider.defaultInstance.workflows,
      contains(isA<WebWorkflow>()));
  }, overrides: <Type, Generator>{
    FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
    FileSystem: () => MemoryFileSystem.test(),
    ProcessManager: () => fakeProcessManager,
  });

  testUsingContext('Fetches tags to get the right version', () async {
    Cache.disableLocking();

    final DoctorCommand doctorCommand = DoctorCommand();
    final CommandRunner<void> commandRunner = createTestCommandRunner(doctorCommand);

    await commandRunner.run(<String>['doctor']);

    expect(flutterVersion.didFetchTagsAndUpdate, true);
    Cache.enableLocking();
  }, overrides: <Type, Generator>{
    ProcessManager: () => FakeProcessManager.any(),
    FileSystem: () => MemoryFileSystem.test(),
    FlutterVersion: () => flutterVersion,
    Doctor: () => NoOpDoctor(),
  }, initializeFlutterRoot: false);

  testUsingContext('If android workflow is disabled, AndroidStudio validator is not included', () {
    expect(DoctorValidatorsProvider.defaultInstance.validators, isNot(contains(isA<AndroidStudioValidator>())));
    expect(DoctorValidatorsProvider.defaultInstance.validators, isNot(contains(isA<NoAndroidStudioValidator>())));
  }, overrides: <Type, Generator>{
    FeatureFlags: () => TestFeatureFlags(isAndroidEnabled: false),
  });
}

class NoOpDoctor implements Doctor {
  @override
  bool get canLaunchAnything => true;

  @override
  bool get canListAnything => true;

  @override
  Future<bool> checkRemoteArtifacts(String engineRevision) async => true;

  @override
  Future<bool> diagnose({
    bool androidLicenses = false,
    bool verbose = true,
    bool showColor = true,
    AndroidLicenseValidator androidLicenseValidator,
    bool showPii = true,
    List<ValidatorTask> startedValidatorTasks,
    bool sendEvent = true,
  }) async => true;

  @override
  List<ValidatorTask> startValidatorTasks() => <ValidatorTask>[];

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

  @override
  List<DoctorValidator> get validators => <DoctorValidator>[];

  @override
  List<Workflow> get workflows => <Workflow>[];
}

class PassingValidator extends DoctorValidator {
  PassingValidator(String name) : super(name);

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage('A helpful message'),
      ValidationMessage('A second, somewhat longer helpful message'),
    ];
    return const ValidationResult(ValidationType.installed, messages, statusInfo: 'with statusInfo');
  }
}

class PiiValidator extends DoctorValidator {
  PiiValidator() : super('PII Validator');

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage('Contains PII path/to/username', piiStrippedMessage: 'Does not contain PII'),
    ];
    return const ValidationResult(ValidationType.installed, messages);
  }
}

class MissingValidator extends DoctorValidator {
  MissingValidator() : super('Missing Validator');

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.error('A useful error message'),
      ValidationMessage('A message that is not an error'),
      ValidationMessage.hint('A hint message'),
    ];
    return const ValidationResult(ValidationType.missing, messages);
  }
}

class NotAvailableValidator extends DoctorValidator {
  NotAvailableValidator() : super('Not Available Validator');

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.error('A useful error message'),
      ValidationMessage('A message that is not an error'),
      ValidationMessage.hint('A hint message'),
    ];
    return const ValidationResult(ValidationType.notAvailable, messages);
  }
}

class StuckValidator extends DoctorValidator {
  StuckValidator() : super('Stuck validator that never completes');

  @override
  Future<ValidationResult> validate() {
    final Completer<ValidationResult> completer = Completer<ValidationResult>();

    // This future will never complete
    return completer.future;
  }
}

class PartialValidatorWithErrors extends DoctorValidator {
  PartialValidatorWithErrors() : super('Partial Validator with Errors');

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.error('An error message indicating partial installation'),
      ValidationMessage.hint('Maybe a hint will help the user'),
      ValidationMessage('An extra message with some verbose details'),
    ];
    return const ValidationResult(ValidationType.partial, messages);
  }
}

class PartialValidatorWithHintsOnly extends DoctorValidator {
  PartialValidatorWithHintsOnly() : super('Partial Validator with only a Hint');

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.hint('There is a hint here'),
      ValidationMessage('But there is no error'),
    ];
    return const ValidationResult(ValidationType.partial, messages);
  }
}

class CrashingValidator extends DoctorValidator {
  CrashingValidator() : super('Crashing validator');

  @override
  Future<ValidationResult> validate() async {
    throw StateError('fatal error');
  }
}

class AsyncCrashingValidator extends DoctorValidator {
  AsyncCrashingValidator(this._time) : super('Async crashing validator');

  final FakeAsync _time;

  @override
  Future<ValidationResult> validate() {
    const Duration delay = Duration(seconds: 1);
    final Future<ValidationResult> result = Future<ValidationResult>.delayed(delay)
      .then((_) {
        throw StateError('fatal error');
      });
    _time.elapse(const Duration(seconds: 1));
    _time.flushMicrotasks();
    return result;
  }
}

/// A doctor that fails with a missing [ValidationResult].
class FakeDoctor extends Doctor {
  FakeDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;

  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      PassingValidator('Passing Validator'),
      MissingValidator(),
      NotAvailableValidator(),
      PartialValidatorWithHintsOnly(),
      PartialValidatorWithErrors(),
    ];
  }
}

/// A doctor that should pass, but still has issues in some categories.
class FakePassingDoctor extends Doctor {
  FakePassingDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      PassingValidator('Passing Validator'),
      PartialValidatorWithHintsOnly(),
      PartialValidatorWithErrors(),
      PassingValidator('Another Passing Validator'),
    ];
  }
}

/// A doctor that should pass, but still has 1 issue to test the singular of
/// categories.
class FakeSinglePassingDoctor extends Doctor {
  FakeSinglePassingDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      PartialValidatorWithHintsOnly(),
    ];
  }
}

/// A doctor that passes and has no issues anywhere.
class FakeQuietDoctor extends Doctor {
  FakeQuietDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      PassingValidator('Passing Validator'),
      PassingValidator('Another Passing Validator'),
      PassingValidator('Validators are fun'),
      PassingValidator('Four score and seven validators ago'),
    ];
  }
}

/// A doctor that passes and contains PII that can be hidden.
class FakePiiDoctor extends Doctor {
  FakePiiDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      PiiValidator(),
    ];
  }
}

/// A doctor with a validator that throws an exception.
class FakeCrashingDoctor extends Doctor {
  FakeCrashingDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    if (_validators == null) {
      _validators = <DoctorValidator>[];
      _validators.add(PassingValidator('Passing Validator'));
      _validators.add(PassingValidator('Another Passing Validator'));
      _validators.add(CrashingValidator());
      _validators.add(PassingValidator('Validators are fun'));
      _validators.add(PassingValidator('Four score and seven validators ago'));
    }
    return _validators;
  }
}

/// A doctor with a validator that will never finish.
class FakeAsyncStuckDoctor extends Doctor {
  FakeAsyncStuckDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    if (_validators == null) {
      _validators = <DoctorValidator>[];
      _validators.add(PassingValidator('Passing Validator'));
      _validators.add(PassingValidator('Another Passing Validator'));
      _validators.add(StuckValidator());
      _validators.add(PassingValidator('Validators are fun'));
      _validators.add(PassingValidator('Four score and seven validators ago'));
    }
    return _validators;
  }
}

/// A doctor with a validator that throws an exception.
class FakeAsyncCrashingDoctor extends Doctor {
  FakeAsyncCrashingDoctor(this._time, Logger logger) : super(logger: logger);

  final FakeAsync _time;

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    if (_validators == null) {
      _validators = <DoctorValidator>[];
      _validators.add(PassingValidator('Passing Validator'));
      _validators.add(PassingValidator('Another Passing Validator'));
      _validators.add(AsyncCrashingValidator(_time));
      _validators.add(PassingValidator('Validators are fun'));
      _validators.add(PassingValidator('Four score and seven validators ago'));
    }
    return _validators;
  }
}

/// A DoctorValidatorsProvider that overrides the default validators without
/// overriding the doctor.
class FakeDoctorValidatorsProvider implements DoctorValidatorsProvider {
  @override
  List<DoctorValidator> get validators {
    return <DoctorValidator>[
      PassingValidator('Passing Validator'),
      PassingValidator('Another Passing Validator'),
      PassingValidator('Providing validators is fun'),
    ];
  }

  @override
  List<Workflow> get workflows => <Workflow>[];
}

class PassingGroupedValidator extends DoctorValidator {
  PassingGroupedValidator(String name) : super(name);

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage('A helpful message'),
    ];
    return const ValidationResult(ValidationType.installed, messages);
  }
}

class MissingGroupedValidator extends DoctorValidator {
  MissingGroupedValidator(String name) : super(name);

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.error('A useful error message'),
    ];
    return const ValidationResult(ValidationType.missing, messages);
  }
}

class PartialGroupedValidator extends DoctorValidator {
  PartialGroupedValidator(String name) : super(name);

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage.error('An error message for partial installation'),
    ];
    return const ValidationResult(ValidationType.partial, messages);
  }
}

class PassingGroupedValidatorWithStatus extends DoctorValidator {
  PassingGroupedValidatorWithStatus(String name) : super(name);

  @override
  Future<ValidationResult> validate() async {
    const List<ValidationMessage> messages = <ValidationMessage>[
      ValidationMessage('A different message'),
    ];
    return const ValidationResult(ValidationType.installed, messages, statusInfo: 'A status message');
  }
}

/// A doctor that has two groups of two validators each.
class FakeGroupedDoctor extends Doctor {
  FakeGroupedDoctor(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      GroupedValidator(<DoctorValidator>[
        PassingGroupedValidator('Category 1'),
        PassingGroupedValidator('Category 1'),
      ]),
      GroupedValidator(<DoctorValidator>[
        PassingGroupedValidator('Category 2'),
        MissingGroupedValidator('Category 2'),
      ]),
    ];
  }
}

class FakeGroupedDoctorWithStatus extends Doctor {
  FakeGroupedDoctorWithStatus(Logger logger) : super(logger: logger);

  List<DoctorValidator> _validators;
  @override
  List<DoctorValidator> get validators {
    return _validators ??= <DoctorValidator>[
      GroupedValidator(<DoctorValidator>[
        PassingGroupedValidator('First validator title'),
        PassingGroupedValidatorWithStatus('Second validator title'),
      ]),
    ];
  }
}

/// A doctor that takes any two validators. Used to check behavior when
/// merging ValidationTypes (installed, missing, partial).
class FakeSmallGroupDoctor extends Doctor {
  FakeSmallGroupDoctor(Logger logger, DoctorValidator val1, DoctorValidator val2) : super(logger: logger) {
    _validators = <DoctorValidator>[GroupedValidator(<DoctorValidator>[val1, val2])];
  }

  List<DoctorValidator> _validators;

  @override
  List<DoctorValidator> get validators => _validators;
}

class VsCodeValidatorTestTargets extends VsCodeValidator {
  VsCodeValidatorTestTargets._(String installDirectory, String extensionDirectory, {String edition})
    : super(VsCode.fromDirectory(installDirectory, extensionDirectory, edition: edition, fileSystem: globals.fs));

  static VsCodeValidatorTestTargets get installedWithExtension =>
      VsCodeValidatorTestTargets._(validInstall, validExtensions);

  static VsCodeValidatorTestTargets get installedWithExtension64bit =>
      VsCodeValidatorTestTargets._(validInstall, validExtensions, edition: '64-bit edition');

  static VsCodeValidatorTestTargets get installedWithoutExtension =>
      VsCodeValidatorTestTargets._(validInstall, missingExtensions);

  static final String validInstall = globals.fs.path.join('test', 'data', 'vscode', 'application');
  static final String validExtensions = globals.fs.path.join('test', 'data', 'vscode', 'extensions');
  static final String missingExtensions = globals.fs.path.join('test', 'data', 'vscode', 'notExtensions');
}

class FakeDeviceManager extends Fake implements DeviceManager {
  List<String> diagnostics = <String>[];
  List<Device> devices = <Device>[];

  @override
  Future<List<Device>> getAllConnectedDevices() async => devices;

  @override
  Future<List<String>> getDeviceDiagnostics() async => diagnostics;
}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
class FakeDevice extends Fake implements Device {
  @override
  String get name => 'name';

  @override
  String get id => 'device-id';

  @override
  Category get category => Category.mobile;

  @override
  bool isSupported() => true;

  @override
  Future<bool> get isLocalEmulator async => false;

  @override
  Future<String> get targetPlatformDisplayName async => 'android';

  @override
  Future<String> get sdkNameAndVersion async => '1.2.3';

  @override
  Future<TargetPlatform> get targetPlatform =>  Future<TargetPlatform>.value(TargetPlatform.android);
}
