// 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 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart' show ProcessException;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/windows/visual_studio.dart';

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

const String programFilesPath = r'C:\Program Files (x86)';
const String visualStudioPath = programFilesPath + r'\Microsoft Visual Studio\2017\Community';
const String cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
const String vswherePath = programFilesPath + r'\Microsoft Visual Studio\Installer\vswhere.exe';

final Platform windowsPlatform = FakePlatform(
  operatingSystem: 'windows',
  environment: <String, String>{
    'PROGRAMFILES(X86)': r'C:\Program Files (x86)\',
  },
);

// A minimum version of a response where a VS installation was found.
const Map<String, dynamic> _defaultResponse = <String, dynamic>{
  'installationPath': visualStudioPath,
  'displayName': 'Visual Studio Community 2019',
  'installationVersion': '16.2.29306.81',
  'isRebootRequired': false,
  'isComplete': true,
  'isLaunchable': true,
  'isPrerelease': false,
  'catalog': <String, dynamic>{
    'productDisplayVersion': '16.2.5',
  },
};

// A minimum version of a response where a VS 2022 installation was found.
const Map<String, dynamic> _vs2022Response = <String, dynamic>{
  'installationPath': visualStudioPath,
  'displayName': 'Visual Studio Community 2022',
  'installationVersion': '17.0.31903.59',
  'isRebootRequired': false,
  'isComplete': true,
  'isLaunchable': true,
  'isPrerelease': false,
  'catalog': <String, dynamic>{
    'productDisplayVersion': '17.0.0',
  },
};

// A minimum version of a response where a Build Tools installation was found.
const Map<String, dynamic> _defaultBuildToolsResponse = <String, dynamic>{
  'installationPath': visualStudioPath,
  'displayName': 'Visual Studio Build Tools 2019',
  'installationVersion': '16.7.30413.136',
  'isRebootRequired': false,
  'isComplete': true,
  'isLaunchable': true,
  'isPrerelease': false,
  'catalog': <String, dynamic>{
    'productDisplayVersion': '16.7.2',
  },
};

// A response for a VS installation that's too old.
const Map<String, dynamic> _tooOldResponse = <String, dynamic>{
  'installationPath': visualStudioPath,
  'displayName': 'Visual Studio Community 2017',
  'installationVersion': '15.9.28307.665',
  'isRebootRequired': false,
  'isComplete': true,
  'isLaunchable': true,
  'isPrerelease': false,
  'catalog': <String, dynamic>{
    'productDisplayVersion': '15.9.12',
  },
};

// A version of a response that doesn't include certain installation status
// information that might be missing in older vswhere.
const Map<String, dynamic> _missingStatusResponse = <String, dynamic>{
  'installationPath': visualStudioPath,
  'displayName': 'Visual Studio Community 2017',
  'installationVersion': '16.4.29609.76',
  'catalog': <String, dynamic>{
    'productDisplayVersion': '16.4.1',
  },
};

const String _malformedDescriptionResponse = r'''
[
  {
    "installationPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community",
    "displayName": "Visual Studio Community 2019",
    "description": "This description has too many "quotes",
    "installationVersion": "16.2.29306.81",
    "isRebootRequired": false,
    "isComplete": true,
    "isPrerelease": false,
    "catalog": {
      "productDisplayVersion": "16.2.5"
    }
  }
]
''';

// Arguments for a vswhere query to search for an installation with the
// requirements.
const List<String> _requirements = <String>[
  'Microsoft.VisualStudio.Workload.NativeDesktop',
  'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
  'Microsoft.VisualStudio.Component.VC.CMake.Project',
];

// Arguments for a vswhere query to search for a Build Tools installation with the
// requirements.
const List<String> _requirementsBuildTools = <String>[
  'Microsoft.VisualStudio.Workload.VCTools',
  'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
  'Microsoft.VisualStudio.Component.VC.CMake.Project',
];

// Sets up the mock environment so that searching for Visual Studio with
// exactly the given required components will provide a result. By default it
// return a preset installation, but the response can be overridden.
void setMockVswhereResponse(
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  List<String>? requiredComponents,
  List<String>? additionalArguments,
  Map<String, dynamic>? response,
  String? responseOverride,
  int? exitCode,
  Exception? exception,
]) {
  fileSystem.file(vswherePath).createSync(recursive: true);
  fileSystem.file(cmakePath).createSync(recursive: true);
  final String finalResponse = responseOverride
    ?? (response != null ? json.encode(<Map<String, dynamic>>[response]) : '[]');
  final List<String> requirementArguments = requiredComponents == null
    ? <String>[]
    : <String>['-requires', ...requiredComponents];

  processManager.addCommand(FakeCommand(
    command: <String>[
      vswherePath,
      '-format',
      'json',
      '-products',
      '*',
      '-utf8',
      '-latest',
      ...?additionalArguments,
      ...requirementArguments,
    ],
    stdout: finalResponse,
    exception: exception,
    exitCode: exitCode ?? 0,
  ));
}

// Sets whether or not a vswhere query with the required components will
// return an installation.
void setMockCompatibleVisualStudioInstallation(
  Map<String, dynamic>? response,
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  int? exitCode,
  Exception? exception,
]) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirements,
    <String>['-version', '16'],
    response,
    null,
    exitCode,
    exception,
  );
}

// Sets whether or not a vswhere query with the required components will
// return a pre-release installation.
void setMockPrereleaseVisualStudioInstallation(
  Map<String, dynamic>? response,
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  int? exitCode,
  Exception? exception,
]) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirements,
    <String>['-version', '16', '-prerelease'],
    response,
    null,
    exitCode,
    exception,
  );
}

// Sets whether or not a vswhere query with the required components will
// return an Build Tools installation.
void setMockCompatibleVisualStudioBuildToolsInstallation(
  Map<String, dynamic>? response,
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  int? exitCode,
  Exception? exception,
]) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirementsBuildTools,
    <String>['-version', '16'],
    response,
    null,
    exitCode,
    exception,
  );
}

// Sets whether or not a vswhere query with the required components will
// return a pre-release Build Tools installation.
void setMockPrereleaseVisualStudioBuildToolsInstallation(
  Map<String, dynamic>? response,
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  int? exitCode,
  Exception? exception,
]) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirementsBuildTools,
    <String>['-version', '16', '-prerelease'],
    response,
    null,
    exitCode,
    exception,
  );
}

// Sets whether or not a vswhere query searching for 'all' and 'prerelease'
// versions will return an installation.
void setMockAnyVisualStudioInstallation(
  Map<String, dynamic>? response,
  FileSystem fileSystem,
  FakeProcessManager processManager, [
  int? exitCode,
  Exception? exception,
]) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    null,
    <String>['-prerelease', '-all'],
    response,
    null,
    exitCode,
    exception,
  );
}

// Set a pre-encoded query result.
void setMockEncodedAnyVisualStudioInstallation(
  String response,
  FileSystem fileSystem,
  FakeProcessManager processManager,
) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    null,
    <String>['-prerelease', '-all'],
    null,
    response,
  );
}

// Sets up the mock environment for a Windows 10 SDK query.
//
// registryPresent controls whether or not the registry key is found.
// filesPresent controls where or not there are any SDK folders at the location
// returned by the registry query.
void setMockSdkRegResponse(
  FileSystem fileSystem,
  FakeProcessManager processManager, {
  bool registryPresent = true,
  bool filesPresent = true,
}) {
  const String registryPath = r'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0';
  const String registryKey = r'InstallationFolder';
  const String installationPath = r'C:\Program Files (x86)\Windows Kits\10\';
  final String stdout = registryPresent
    ? '''
$registryPath
    $registryKey    REG_SZ    $installationPath
'''
    : '''

ERROR: The system was unable to find the specified registry key or value.
''';

  if (filesPresent) {
    final Directory includeDirectory =  fileSystem.directory(installationPath).childDirectory('Include');
    includeDirectory.childDirectory('10.0.17763.0').createSync(recursive: true);
    includeDirectory.childDirectory('10.0.18362.0').createSync(recursive: true);
    // Not an actual version; added to ensure that version comparison is number, not string-based.
    includeDirectory.childDirectory('10.0.184.0').createSync(recursive: true);
  }

  processManager.addCommand(FakeCommand(
    command: const <String>[
      'reg',
      'query',
      registryPath,
      '/v',
      registryKey,
    ],
    stdout: stdout,
  ));
}

// Create a visual studio instance with a FakeProcessManager.
VisualStudioFixture setUpVisualStudio() {
  final FakeProcessManager processManager = FakeProcessManager.empty();
  final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
  final BufferLogger logger = BufferLogger.test();
  final VisualStudio visualStudio = VisualStudio(
    fileSystem: fileSystem,
    platform: windowsPlatform,
    logger: logger,
    processManager: processManager,
  );
  return VisualStudioFixture(visualStudio, fileSystem, processManager, logger);
}

// Set all vswhere query with the required components return null.
void setNoViableToolchainInstallation(
  VisualStudioFixture fixture,
) {
  setMockCompatibleVisualStudioInstallation(
    null,
    fixture.fileSystem,
    fixture.processManager,
  );
  setMockCompatibleVisualStudioBuildToolsInstallation(
    null,
    fixture.fileSystem,
    fixture.processManager,
  );
  setMockPrereleaseVisualStudioInstallation(
    null,
    fixture.fileSystem,
    fixture.processManager,
  );
  setMockPrereleaseVisualStudioBuildToolsInstallation(
    null,
    fixture.fileSystem,
    fixture.processManager,
  );
}

void main() {
  group('Visual Studio', () {
    testWithoutContext('isInstalled throws when PROGRAMFILES(X86) env not set', () {
      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: MemoryFileSystem.test(style: FileSystemStyle.windows),
        platform: FakePlatform(operatingSystem: 'windows'),
        processManager: FakeProcessManager.any(),
      );

      expect(() => visualStudio.isInstalled,
          throwsToolExit(message: '%PROGRAMFILES(X86)% environment variable not found'));
    });

    testWithoutContext('isInstalled and cmakePath correct when vswhere is missing', () {
      final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
      const Exception exception = ProcessException('vswhere', <String>[]);
      final FakeProcessManager fakeProcessManager = FakeProcessManager.empty();

      setMockCompatibleVisualStudioInstallation(null, fileSystem, fakeProcessManager, null, exception);
      setMockCompatibleVisualStudioBuildToolsInstallation(null, fileSystem, fakeProcessManager, null, exception);
      setMockPrereleaseVisualStudioInstallation(null, fileSystem, fakeProcessManager, null, exception);
      setMockPrereleaseVisualStudioBuildToolsInstallation(null, fileSystem, fakeProcessManager, null, exception);
      setMockAnyVisualStudioInstallation(null, fileSystem, fakeProcessManager, null, exception);

      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: fileSystem,
        platform: windowsPlatform,
        processManager: fakeProcessManager,
      );

      expect(visualStudio.isInstalled, false);
      expect(visualStudio.cmakePath, isNull);
    });

    testWithoutContext(
        'isInstalled returns false when vswhere returns non-zero', () {
      final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
      final FakeProcessManager fakeProcessManager = FakeProcessManager.empty();

      setMockCompatibleVisualStudioInstallation(null, fileSystem, fakeProcessManager, 1);
      setMockCompatibleVisualStudioBuildToolsInstallation(null, fileSystem, fakeProcessManager, 1);
      setMockPrereleaseVisualStudioInstallation(null, fileSystem, fakeProcessManager, 1);
      setMockPrereleaseVisualStudioBuildToolsInstallation(null, fileSystem, fakeProcessManager, 1);
      setMockAnyVisualStudioInstallation(null, fileSystem, fakeProcessManager, 1);

      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: fileSystem,
        platform: windowsPlatform,
        processManager: fakeProcessManager,
      );

      expect(visualStudio.isInstalled, false);
      expect(visualStudio.cmakePath, isNull);
    });

    testWithoutContext('VisualStudio getters return the right values if no installation is found', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, false);
      expect(visualStudio.isAtLeastMinimumVersion, false);
      expect(visualStudio.hasNecessaryComponents, false);
      expect(visualStudio.isComplete, false);
      expect(visualStudio.isRebootRequired, false);
      expect(visualStudio.isLaunchable, false);
      expect(visualStudio.displayName, null);
      expect(visualStudio.displayVersion, null);
      expect(visualStudio.installLocation, null);
      expect(visualStudio.fullVersion, null);
    });

    testWithoutContext('necessaryComponentDescriptions suggest the right VS tools on major version 16', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockCompatibleVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      final String toolsString = visualStudio.necessaryComponentDescriptions()[0];

      expect(toolsString.contains('v142'), true);
    });

    testWithoutContext('necessaryComponentDescriptions suggest the right VS tools on an old version', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _tooOldResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      final String toolsString = visualStudio.necessaryComponentDescriptions()[0];

      expect(toolsString.contains('v142'), true);
    });

    testWithoutContext('isInstalled returns true even with missing status information', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _missingStatusResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
    });

    testWithoutContext('isInstalled returns true when VS is present but missing components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
    });

    testWithoutContext('isInstalled returns true when VS is present but too old', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _tooOldResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
    });

    testWithoutContext('isInstalled returns true when a prerelease version of VS is present', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isPrerelease'] = true;
      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockCompatibleVisualStudioBuildToolsInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isPrerelease, true);
    });

    testWithoutContext('isInstalled returns true when a prerelease version of Build Tools is present', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultBuildToolsResponse)
        ..['isPrerelease'] = true;
      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockCompatibleVisualStudioBuildToolsInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioBuildToolsInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isPrerelease, true);
    });

    testWithoutContext('isAtLeastMinimumVersion returns false when the version found is too old', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _tooOldResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, false);
    });

    testWithoutContext('isComplete returns false when an incomplete installation is found', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isComplete'] = false;
      setMockAnyVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isComplete, false);
    });

    testWithoutContext(
        "isLaunchable returns false if the installation can't be launched", () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isLaunchable'] = false;
      setMockAnyVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isLaunchable, false);
    });

    testWithoutContext('isRebootRequired returns true if the installation needs a reboot', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isRebootRequired'] = true;
      setMockAnyVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isRebootRequired, true);
    });

    testWithoutContext('hasNecessaryComponents returns false when VS is present but missing components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.hasNecessaryComponents, false);
    });

    testWithoutContext('cmakePath returns null when VS is present but missing components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.cmakePath, isNull);
    });

    testWithoutContext('cmakePath returns null when VS is present but with require components but installation is faulty', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isRebootRequired'] = true;
      setMockCompatibleVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.cmakePath, isNull);
    });

    testWithoutContext('hasNecessaryComponents returns false when VS is present with required components but installation is faulty', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['isRebootRequired'] = true;
      setMockCompatibleVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.hasNecessaryComponents, false);
    });

    testWithoutContext('VS metadata is available when VS is present, even if missing components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockAnyVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.displayName, equals('Visual Studio Community 2019'));
      expect(visualStudio.displayVersion, equals('16.2.5'));
      expect(visualStudio.installLocation, equals(visualStudioPath));
      expect(visualStudio.fullVersion, equals('16.2.29306.81'));
    });

    testWithoutContext('Warns and returns no installation when VS is present but vswhere returns invalid JSON', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setNoViableToolchainInstallation(fixture);

      setMockEncodedAnyVisualStudioInstallation(
        '{',
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, isFalse);
      expect(visualStudio.isComplete, isFalse);
      expect(visualStudio.isLaunchable, isFalse);
      expect(visualStudio.isPrerelease, isFalse);
      expect(visualStudio.isRebootRequired, isFalse);
      expect(visualStudio.hasNecessaryComponents, isFalse);
      expect(visualStudio.displayName, isNull);
      expect(visualStudio.displayVersion, isNull);
      expect(visualStudio.installLocation, isNull);
      expect(visualStudio.fullVersion, isNull);
      expect(visualStudio.cmakePath, isNull);

      expect(fixture.logger.warningText, contains('Warning: Unexpected vswhere.exe JSON output'));
    });

    testWithoutContext('Everything returns good values when VS is present with all components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockCompatibleVisualStudioInstallation(
        _defaultResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
    });

    testWithoutContext('Everything returns good values when Build Tools is present with all components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockCompatibleVisualStudioBuildToolsInstallation(
        _defaultBuildToolsResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
    });

    testWithoutContext('properties return the right value for Visual Studio 2022', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockCompatibleVisualStudioInstallation(
        _vs2022Response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 17 2022'));
    });

    testWithoutContext('Metadata is for compatible version when latest is missing components', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      // Return a different version for queries without the required packages.
      final Map<String, dynamic> olderButCompleteVersionResponse = <String, dynamic>{
        'installationPath': visualStudioPath,
        'displayName': 'Visual Studio Community 2017',
        'installationVersion': '15.9.28307.665',
        'catalog': <String, dynamic>{
          'productDisplayVersion': '15.9.12',
        },
      };

      setMockCompatibleVisualStudioInstallation(
        olderButCompleteVersionResponse,
        fixture.fileSystem,
        fixture.processManager,
      );
      // Return a different version for queries without the required packages.
      final Map<String, dynamic> incompleteVersionResponse = <String, dynamic>{
        'installationPath': visualStudioPath,
        'displayName': 'Visual Studio Community 2019',
        'installationVersion': '16.1.1.1',
        'catalog': <String, String>{
          'productDisplayVersion': '16.1',
        },
      };
      setMockAnyVisualStudioInstallation(
        incompleteVersionResponse,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.displayName, equals('Visual Studio Community 2017'));
      expect(visualStudio.displayVersion, equals('15.9.12'));
    });

    testWithoutContext('SDK version returns the latest version when present', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockSdkRegResponse(
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.getWindows10SDKVersion(), '10.0.18362.0');
    });

    testWithoutContext('SDK version returns null when the registry key is not present', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockSdkRegResponse(
        fixture.fileSystem,
        fixture.processManager,
        registryPresent: false,
      );

      expect(visualStudio.getWindows10SDKVersion(), null);
    });

    testWithoutContext('SDK version returns null when there are no SDK files present', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockSdkRegResponse(
        fixture.fileSystem,
        fixture.processManager,
        filesPresent: false,
      );

      expect(visualStudio.getWindows10SDKVersion(), null);
    });
  });

  // The output of vswhere.exe is known to contain bad UTF8.
  // See: https://github.com/flutter/flutter/issues/102451
  group('Correctly handles bad UTF-8 from vswhere.exe output', () {
    late VisualStudioFixture fixture;
    late VisualStudio visualStudio;

    setUp(() {
      fixture = setUpVisualStudio();
      visualStudio = fixture.visualStudio;
    });

    testWithoutContext('Ignores unicode replacement char in unused properties', () {
      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['unused'] = 'Bad UTF8 \u{FFFD}';

      setMockCompatibleVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
    });

    testWithoutContext('Throws ToolExit on bad UTF-8 in installationPath', () {
      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['installationPath'] = '\u{FFFD}';

      setMockCompatibleVisualStudioInstallation(response, fixture.fileSystem, fixture.processManager);

      expect(() => visualStudio.isInstalled,
          throwsToolExit(message: 'Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found in string'));
    });

    testWithoutContext('Throws ToolExit on bad UTF-8 in installationVersion', () {
      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['installationVersion'] = '\u{FFFD}';

      setMockCompatibleVisualStudioInstallation(response, fixture.fileSystem, fixture.processManager);

      expect(() => visualStudio.isInstalled,
          throwsToolExit(message: 'Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found in string'));
    });

    testWithoutContext('Ignores bad UTF-8 in displayName', () {
      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['displayName'] = '\u{FFFD}';

      setMockCompatibleVisualStudioInstallation(response, fixture.fileSystem, fixture.processManager);

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
      expect(visualStudio.displayName, equals('\u{FFFD}'));
    });

    testWithoutContext("Ignores bad UTF-8 in catalog's productDisplayVersion", () {
      final Map<String, dynamic> catalog = Map<String, dynamic>.of(_defaultResponse['catalog'] as Map<String, dynamic>)
        ..['productDisplayVersion'] = '\u{FFFD}';
      final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
        ..['catalog'] = catalog;

      setMockCompatibleVisualStudioInstallation(response, fixture.fileSystem, fixture.processManager);

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
      expect(visualStudio.displayVersion, equals('\u{FFFD}'));
    });

    testWithoutContext('Ignores malformed JSON in description property', () {
      setMockVswhereResponse(
        fixture.fileSystem,
        fixture.processManager,
        _requirements,
        <String>['-version', '16'],
        null,
        _malformedDescriptionResponse,
      );

      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isAtLeastMinimumVersion, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.cmakePath, equals(cmakePath));
      expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
      expect(visualStudio.displayVersion, equals('16.2.5'));

      expect(fixture.logger.warningText, isEmpty);
    });
  });

  group(VswhereDetails, () {
      test('Accepts empty JSON', () {
        const bool meetsRequirements = true;
        final Map<String, dynamic> json = <String, dynamic>{};

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);

        expect(result.installationPath, null);
        expect(result.displayName, null);
        expect(result.fullVersion, null);
        expect(result.isComplete, null);
        expect(result.isLaunchable, null);
        expect(result.isRebootRequired, null);
        expect(result.isPrerelease, null);
        expect(result.catalogDisplayVersion, null);
        expect(result.isUsable, isTrue);
      });

      test('Ignores unknown JSON properties', () {
        const bool meetsRequirements = true;
        final Map<String, dynamic> json = <String, dynamic>{
          'hello': 'world',
        };

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);

        expect(result.installationPath, null);
        expect(result.displayName, null);
        expect(result.fullVersion, null);
        expect(result.isComplete, null);
        expect(result.isLaunchable, null);
        expect(result.isRebootRequired, null);
        expect(result.isPrerelease, null);
        expect(result.catalogDisplayVersion, null);
        expect(result.isUsable, isTrue);
      });

      test('Accepts JSON', () {
        const bool meetsRequirements = true;

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse);

        expect(result.installationPath, visualStudioPath);
        expect(result.displayName, 'Visual Studio Community 2019');
        expect(result.fullVersion, '16.2.29306.81');
        expect(result.isComplete, true);
        expect(result.isLaunchable, true);
        expect(result.isRebootRequired, false);
        expect(result.isPrerelease, false);
        expect(result.catalogDisplayVersion, '16.2.5');
        expect(result.isUsable, isTrue);
      });

      test('Installation that does not satisfy requirements is not usable', () {
        const bool meetsRequirements = false;

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse);

        expect(result.isUsable, isFalse);
      });

      test('Incomplete installation is not usable', () {
        const bool meetsRequirements = true;
        final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
          ..['isComplete'] = false;

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);

        expect(result.isUsable, isFalse);
      });

      test('Unlaunchable installation is not usable', () {
        const bool meetsRequirements = true;
        final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
          ..['isLaunchable'] = false;

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);

        expect(result.isUsable, isFalse);
      });

      test('Installation that requires reboot is not usable', () {
        const bool meetsRequirements = true;
        final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
          ..['isRebootRequired'] = true;

        final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);

        expect(result.isUsable, isFalse);
      });
  });
}

class VisualStudioFixture {
  VisualStudioFixture(this.visualStudio, this.fileSystem, this.processManager, this.logger);

  final VisualStudio visualStudio;
  final FileSystem fileSystem;
  final FakeProcessManager processManager;
  final BufferLogger logger;
}
