// 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 'package:mockito/mockito.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.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 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',
  },
};

// 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',
];

// 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,
]) {
  fileSystem.file(vswherePath).createSync(recursive: true);
  fileSystem.file(cmakePath).createSync(recursive: true);
  final String finalResponse = responseOverride
    ?? json.encode(<Map<String, dynamic>>[response]);
  final List<String> requirementArguments = requiredComponents == null
    ? <String>[]
    : <String>['-requires', ...requiredComponents];

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

// 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,
) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirements,
    <String>['-version', '16'],
    response,
  );
}

// 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,
) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    _requirements,
    <String>['-version', '16', '-prerelease'],
    response,
  );
}

// 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,
) {
  setMockVswhereResponse(
    fileSystem,
    processManager,
    null,
    <String>['-prerelease', '-all'],
    response,
  );
}

// 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 controles 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.list(<FakeCommand>[]);
  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);
}

void main() {
  group('Visual Studio', () {
    testWithoutContext('isInstalled returns false when vswhere is missing', () {
      final MockProcessManager mockProcessManager = MockProcessManager();
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
        stdoutEncoding: utf8,
        stderrEncoding: utf8,
      )).thenThrow(const ProcessException('vswhere', <String>[]));
      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: MemoryFileSystem.test(style: FileSystemStyle.windows),
        platform: windowsPlatform,
        processManager: mockProcessManager,
      );

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

    testWithoutContext('cmakePath returns null when vswhere is missing', () {
      final MockProcessManager mockProcessManager = MockProcessManager();
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
        stdoutEncoding: utf8,
        stderrEncoding: utf8,
      )).thenThrow(const ProcessException('vswhere', <String>[]));
      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: MemoryFileSystem.test(style: FileSystemStyle.windows),
        platform: windowsPlatform,
        processManager: mockProcessManager,
      );

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

    testWithoutContext(
        'isInstalled returns false when vswhere returns non-zero', () {
      final MockProcessManager mockProcessManager = MockProcessManager();
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
        stdoutEncoding: utf8,
        stderrEncoding: utf8,
      )).thenAnswer((Invocation invocation) {
        return FakeProcessResult(exitCode: 1, stderr: '', stdout: '');
      });
      final VisualStudio visualStudio = VisualStudio(
        logger: BufferLogger.test(),
        fileSystem: MemoryFileSystem.test(style: FileSystemStyle.windows),
        platform: windowsPlatform,
        processManager: mockProcessManager,
      );

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

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

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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,
      );
      setMockPrereleaseVisualStudioInstallation(
        response,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockAnyVisualStudioInstallation(
        null,
        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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );

      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );

      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );

      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        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,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        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;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      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('cmakePath returns null when VS is present but when vswhere returns invalid JSON', () {
      final VisualStudioFixture fixture = setUpVisualStudio();
      final VisualStudio visualStudio = fixture.visualStudio;

      setMockCompatibleVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockEncodedAnyVisualStudioInstallation(
        '{',
        fixture.fileSystem,
        fixture.processManager,
      );

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

    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,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );
      setMockAnyVisualStudioInstallation(
        null,
        fixture.fileSystem,
        fixture.processManager,
      );

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

    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,
      );
      setMockPrereleaseVisualStudioInstallation(
        null,
        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);
    });
  });
}

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

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

class MockProcessManager extends Mock implements ProcessManager {}
