// 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:meta/meta.dart';
import 'package:process/process.dart';

import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../convert.dart';

/// Encapsulates information about the installed copy of Visual Studio, if any.
class VisualStudio {
  VisualStudio({
    required FileSystem fileSystem,
    required ProcessManager processManager,
    required Platform platform,
    required Logger logger,
  }) : _platform = platform,
       _fileSystem = fileSystem,
       _processUtils = ProcessUtils(processManager: processManager, logger: logger),
       _logger = logger;

  final FileSystem _fileSystem;
  final Platform _platform;
  final ProcessUtils _processUtils;
  final Logger _logger;

  /// Matches the description property from the vswhere.exe JSON output.
  final RegExp _vswhereDescriptionProperty = RegExp(r'\s*"description"\s*:\s*".*"\s*,?');

  /// True if Visual Studio installation was found.
  ///
  /// Versions older than 2017 Update 2 won't be detected, so error messages to
  /// users should take into account that [false] may mean that the user may
  /// have an old version rather than no installation at all.
  bool get isInstalled => _bestVisualStudioDetails != null;

  bool get isAtLeastMinimumVersion {
    final int? installedMajorVersion = _majorVersion;
    return installedMajorVersion != null && installedMajorVersion >= _minimumSupportedVersion;
  }

  /// True if there is a version of Visual Studio with all the components
  /// necessary to build the project.
  bool get hasNecessaryComponents => _bestVisualStudioDetails?.isUsable ?? false;

  /// The name of the Visual Studio install.
  ///
  /// For instance: "Visual Studio Community 2019". This should only be used for
  /// display purposes.
  String? get displayName => _bestVisualStudioDetails?.displayName;

  /// The user-friendly version number of the Visual Studio install.
  ///
  /// For instance: "15.4.0". This should only be used for display purposes.
  /// Logic based off the installation's version should use the `fullVersion`.
  String? get displayVersion => _bestVisualStudioDetails?.catalogDisplayVersion;

  /// The directory where Visual Studio is installed.
  String? get installLocation => _bestVisualStudioDetails?.installationPath;

  /// The full version of the Visual Studio install.
  ///
  /// For instance: "15.4.27004.2002".
  String? get fullVersion => _bestVisualStudioDetails?.fullVersion;

  // Properties that determine the status of the installation. There might be
  // Visual Studio versions that don't include them, so default to a "valid" value to
  // avoid false negatives.

  /// True if there is a complete installation of Visual Studio.
  ///
  /// False if installation is not found.
  bool get isComplete {
    if (_bestVisualStudioDetails == null) {
      return false;
    }
    return _bestVisualStudioDetails!.isComplete ?? true;
  }

  /// True if Visual Studio is launchable.
  ///
  /// False if installation is not found.
  bool get isLaunchable {
    if (_bestVisualStudioDetails == null) {
      return false;
    }
    return _bestVisualStudioDetails!.isLaunchable ?? true;
  }

  /// True if the Visual Studio installation is a pre-release version.
  bool get isPrerelease => _bestVisualStudioDetails?.isPrerelease ?? false;

  /// True if a reboot is required to complete the Visual Studio installation.
  bool get isRebootRequired => _bestVisualStudioDetails?.isRebootRequired ?? false;

  /// The name of the recommended Visual Studio installer workload.
  String get workloadDescription => 'Desktop development with C++';

  /// Returns the highest installed Windows 10 SDK version, or null if none is
  /// found.
  ///
  /// For instance: 10.0.18362.0.
  String? getWindows10SDKVersion() {
    final String? sdkLocation = _getWindows10SdkLocation();
    if (sdkLocation == null) {
      return null;
    }
    final Directory sdkIncludeDirectory = _fileSystem.directory(sdkLocation).childDirectory('Include');
    if (!sdkIncludeDirectory.existsSync()) {
      return null;
    }
    // The directories in this folder are named by the SDK version.
    Version? highestVersion;
    for (final FileSystemEntity versionEntry in sdkIncludeDirectory.listSync()) {
      if (versionEntry.basename.startsWith('10.')) {
        // Version only handles 3 components; strip off the '10.' to leave three
        // components, since they all start with that.
        final Version? version = Version.parse(versionEntry.basename.substring(3));
        if (highestVersion == null || (version != null && version > highestVersion)) {
          highestVersion = version;
        }
      }
    }
    if (highestVersion == null) {
      return null;
    }
    return '10.$highestVersion';
  }

  /// The names of the components within the workload that must be installed.
  ///
  /// The descriptions of some components differ from version to version. When
  /// a supported version is present, the descriptions used will be for that
  /// version.
  List<String> necessaryComponentDescriptions() {
    return _requiredComponents().values.toList();
  }

  /// The consumer-facing version name of the minimum supported version.
  ///
  /// E.g., for Visual Studio 2019 this returns "2019" rather than "16".
  String get minimumVersionDescription {
    return '2019';
  }

  /// The path to CMake, or null if no Visual Studio installation has
  /// the components necessary to build.
  String? get cmakePath {
    final VswhereDetails? details = _bestVisualStudioDetails;
    if (details == null || !details.isUsable || details.installationPath == null) {
      return null;
    }

    return _fileSystem.path.joinAll(<String>[
      details.installationPath!,
      'Common7',
      'IDE',
      'CommonExtensions',
      'Microsoft',
      'CMake',
      'CMake',
      'bin',
      'cmake.exe',
    ]);
  }

  /// The generator string to pass to CMake to select this Visual Studio
  /// version.
  String? get cmakeGenerator {
    // From https://cmake.org/cmake/help/v3.22/manual/cmake-generators.7.html#visual-studio-generators
    switch (_majorVersion) {
      case 17:
        return 'Visual Studio 17 2022';
      case 16:
      default:
        return 'Visual Studio 16 2019';
    }
  }

  /// The major version of the Visual Studio install, as an integer.
  int? get _majorVersion => fullVersion != null ? int.tryParse(fullVersion!.split('.')[0]) : null;

  /// The path to vswhere.exe.
  ///
  /// vswhere should be installed for VS 2017 Update 2 and later; if it's not
  /// present then there isn't a new enough installation of VS. This path is
  /// not user-controllable, unlike the install location of Visual Studio
  /// itself.
  String get _vswherePath {
    const String programFilesEnv = 'PROGRAMFILES(X86)';
    if (!_platform.environment.containsKey(programFilesEnv)) {
      throwToolExit('%$programFilesEnv% environment variable not found.');
    }
    return _fileSystem.path.join(
      _platform.environment[programFilesEnv]!,
      'Microsoft Visual Studio',
      'Installer',
      'vswhere.exe',
    );
  }

  /// Workload ID for use with vswhere requirements.
  ///
  /// Workload ID is different between Visual Studio IDE and Build Tools.
  /// See https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
  static const List<String> _requiredWorkloads = <String>[
    'Microsoft.VisualStudio.Workload.NativeDesktop',
    'Microsoft.VisualStudio.Workload.VCTools',
  ];

  /// Components for use with vswhere requirements.
  ///
  /// Maps from component IDs to description in the installer UI.
  /// See https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
  Map<String, String> _requiredComponents([int? majorVersion]) {
    // The description of the C++ toolchain required by the template. The
    // component name is significantly different in different versions.
    // When a new major version of VS is supported, its toolchain description
    // should be added below. It should also be made the default, so that when
    // there is no installation, the message shows the string that will be
    // relevant for the most likely fresh install case).
    String cppToolchainDescription;
    switch (majorVersion ?? _majorVersion) {
      case 16:
      default:
        cppToolchainDescription = 'MSVC v142 - VS 2019 C++ x64/x86 build tools';
    }
    // The 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' ID is assigned to the latest
    // release of the toolchain, and there can be minor updates within a given version of
    // Visual Studio. Since it changes over time, listing a precise version would become
    // wrong after each VC++ toolchain update, so just instruct people to install the
    // latest version.
    cppToolchainDescription += '\n   - If there are multiple build tool versions available, install the latest';
    // Things which are required by the workload (e.g., MSBuild) don't need to
    // be included here.
    return <String, String>{
      // The C++ toolchain required by the template.
      'Microsoft.VisualStudio.Component.VC.Tools.x86.x64': cppToolchainDescription,
      // CMake
      'Microsoft.VisualStudio.Component.VC.CMake.Project': 'C++ CMake tools for Windows',
    };
  }

  /// The minimum supported major version.
  static const int _minimumSupportedVersion = 16;  // '16' is VS 2019.

  /// vswhere argument to specify the minimum version.
  static const String _vswhereMinVersionArgument = '-version';

  /// vswhere argument to allow prerelease versions.
  static const String _vswherePrereleaseArgument = '-prerelease';

  /// The registry path for Windows 10 SDK installation details.
  static const String _windows10SdkRegistryPath = r'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0';

  /// The registry key in _windows10SdkRegistryPath for the folder where the
  /// SDKs are installed.
  static const String _windows10SdkRegistryKey = 'InstallationFolder';

  /// Returns the details of the newest version of Visual Studio.
  ///
  /// If [validateRequirements] is set, the search will be limited to versions
  /// that have all of the required workloads and components.
  VswhereDetails? _visualStudioDetails({
      bool validateRequirements = false,
      List<String>? additionalArguments,
      String? requiredWorkload
    }) {
    final List<String> requirementArguments = validateRequirements
        ? <String>[
            if (requiredWorkload != null) ...<String>[
              '-requires',
              requiredWorkload,
            ],
            ..._requiredComponents(_minimumSupportedVersion).keys,
          ]
        : <String>[];
    try {
      final List<String> defaultArguments = <String>[
        '-format', 'json',
        '-products', '*',
        '-utf8',
        '-latest',
      ];
      // Ignore replacement characters as vswhere.exe is known to output them.
      // See: https://github.com/flutter/flutter/issues/102451
      const Encoding encoding = Utf8Codec(reportErrors: false);
      final RunResult whereResult = _processUtils.runSync(<String>[
        _vswherePath,
        ...defaultArguments,
        ...?additionalArguments,
        ...requirementArguments,
      ], encoding: encoding);
      if (whereResult.exitCode == 0) {
        final List<Map<String, dynamic>>? installations = _tryDecodeVswhereJson(whereResult.stdout);
        if (installations != null && installations.isNotEmpty) {
          return VswhereDetails.fromJson(validateRequirements, installations[0]);
        }
      }
    } on ArgumentError {
      // Thrown if vswhere doesn't exist; ignore and return null below.
    } on ProcessException {
      // Ignored, return null below.
    }
    return null;
  }

  List<Map<String, dynamic>>? _tryDecodeVswhereJson(String vswhereJson) {
    List<dynamic>? result;
    FormatException? originalError;
    try {
      // Some versions of vswhere.exe are known to encode their output incorrectly,
      // resulting in invalid JSON in the 'description' property when interpreted
      // as UTF-8. First, try to decode without any pre-processing.
      try {
        result = json.decode(vswhereJson) as List<dynamic>;
      } on FormatException catch (error) {
        // If that fails, remove the 'description' property and try again.
        // See: https://github.com/flutter/flutter/issues/106601
        vswhereJson = vswhereJson.replaceFirst(_vswhereDescriptionProperty, '');

        _logger.printTrace('Failed to decode vswhere.exe JSON output. $error'
          'Retrying after removing the unused description property:\n$vswhereJson');

        originalError = error;
        result = json.decode(vswhereJson) as List<dynamic>;
      }
    } on FormatException {
      // Removing the description property didn't help.
      // Report the original decoding error on the unprocessed JSON.
      _logger.printWarning('Warning: Unexpected vswhere.exe JSON output. $originalError'
        'To see the full JSON, run flutter doctor -vv.');
      return null;
    }

    return result.cast<Map<String, dynamic>>();
  }

  /// Returns the details of the best available version of Visual Studio.
  ///
  /// If there's a version that has all the required components, that
  /// will be returned, otherwise returns the latest installed version regardless
  /// of components and version, or null if no such installation is found.
  late final VswhereDetails?  _bestVisualStudioDetails = () {
    // First, attempt to find the latest version of Visual Studio that satisfies
    // both the minimum supported version and the required workloads.
    // Check in the order of stable VS, stable BT, pre-release VS, pre-release BT.
    final List<String> minimumVersionArguments = <String>[
      _vswhereMinVersionArgument,
      _minimumSupportedVersion.toString(),
    ];
    for (final bool checkForPrerelease in <bool>[false, true]) {
      for (final String requiredWorkload in _requiredWorkloads) {
        final VswhereDetails? result = _visualStudioDetails(
          validateRequirements: true,
          additionalArguments: checkForPrerelease
              ? <String>[...minimumVersionArguments, _vswherePrereleaseArgument]
              : minimumVersionArguments,
          requiredWorkload: requiredWorkload);

          if (result != null) {
            return result;
          }
      }
    }

    // An installation that satisfies requirements could not be found.
    // Fallback to the latest Visual Studio installation.
    return _visualStudioDetails(
        additionalArguments: <String>[_vswherePrereleaseArgument, '-all']);
  }();

  /// Returns the installation location of the Windows 10 SDKs, or null if the
  /// registry doesn't contain that information.
  String? _getWindows10SdkLocation() {
    try {
      final RunResult result = _processUtils.runSync(<String>[
        'reg',
        'query',
        _windows10SdkRegistryPath,
        '/v',
        _windows10SdkRegistryKey,
      ]);
      if (result.exitCode == 0) {
        final RegExp pattern = RegExp(r'InstallationFolder\s+REG_SZ\s+(.+)');
        final RegExpMatch? match = pattern.firstMatch(result.stdout);
        if (match != null) {
          return match.group(1)!.trim();
        }
      }
    } on ArgumentError {
      // Thrown if reg somehow doesn't exist; ignore and return null below.
    } on ProcessException {
      // Ignored, return null below.
    }
    return null;
  }

  /// Returns the highest-numbered SDK version in [dir], which should be the
  /// Windows 10 SDK installation directory.
  ///
  /// Returns null if no Windows 10 SDKs are found.
  String? findHighestVersionInSdkDirectory(Directory dir) {
    // This contains subfolders that are named by the SDK version.
    final Directory includeDir = dir.childDirectory('Includes');
    if (!includeDir.existsSync()) {
      return null;
    }
    Version? highestVersion;
    for (final FileSystemEntity versionEntry in includeDir.listSync()) {
      if (!versionEntry.basename.startsWith('10.')) {
        continue;
      }
      // Version only handles 3 components; strip off the '10.' to leave three
      // components, since they all start with that.
      final Version? version = Version.parse(versionEntry.basename.substring(3));
      if (highestVersion == null || (version != null && version > highestVersion)) {
        highestVersion = version;
      }
    }
    // Re-add the leading '10.' that was removed for comparison.
    return highestVersion == null ? null : '10.$highestVersion';
  }
}

/// The details of a Visual Studio installation according to vswhere.
@visibleForTesting
class VswhereDetails {
  const VswhereDetails({
    required this.meetsRequirements,
    required this.installationPath,
    required this.displayName,
    required this.fullVersion,
    required this.isComplete,
    required this.isLaunchable,
    required this.isRebootRequired,
    required this.isPrerelease,
    required this.catalogDisplayVersion,
  });

  /// Create a `VswhereDetails` from the JSON output of vswhere.exe.
  factory VswhereDetails.fromJson(
    bool meetsRequirements,
    Map<String, dynamic> details
  ) {
    final Map<String, dynamic>? catalog = details['catalog'] as Map<String, dynamic>?;

    return VswhereDetails(
      meetsRequirements: meetsRequirements,
      isComplete: details['isComplete'] as bool?,
      isLaunchable: details['isLaunchable'] as bool?,
      isRebootRequired: details['isRebootRequired'] as bool?,
      isPrerelease: details['isPrerelease'] as bool?,

      // Below are strings that must be well-formed without replacement characters.
      installationPath: _validateString(details['installationPath'] as String?),
      fullVersion: _validateString(details['installationVersion'] as String?),

      // Below are strings that are used only for display purposes and are allowed to
      // contain replacement characters.
      displayName: details['displayName'] as String?,
      catalogDisplayVersion: catalog == null ? null : catalog['productDisplayVersion'] as String?,
    );
  }

  /// Verify JSON strings from vswhere.exe output are valid.
  ///
  /// The output of vswhere.exe is known to output replacement characters.
  /// Use this to ensure values that must be well-formed are valid. Strings that
  /// are only used for display purposes should skip this check.
  /// See: https://github.com/flutter/flutter/issues/102451
  static String? _validateString(String? value) {
    if (value != null && value.contains('\u{FFFD}')) {
      throwToolExit(
        'Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found in string: $value. '
        'The Flutter team would greatly appreciate if you could file a bug explaining '
        'exactly what you were doing when this happened:\n'
        'https://github.com/flutter/flutter/issues/new/choose\n');
    }

    return value;
  }

  /// Whether the installation satisfies the required workloads and minimum version.
  final bool meetsRequirements;

  /// The root directory of the Visual Studio installation.
  final String? installationPath;

  /// The user-friendly name of the installation.
  final String? displayName;

  /// The complete version.
  final String? fullVersion;

  /// Keys for the status of the installation.
  final bool? isComplete;
  final bool? isLaunchable;
  final bool? isRebootRequired;

  /// The key for a pre-release version.
  final bool? isPrerelease;

  /// The user-friendly version.
  final String? catalogDisplayVersion;

  /// Checks if the Visual Studio installation can be used by Flutter.
  ///
  /// Returns false if the installation has issues the user must resolve.
  /// This may return true even if required information is missing as older
  /// versions of Visual Studio might not include them.
  bool get isUsable {
    if (!meetsRequirements) {
      return false;
    }

    if (!(isComplete ?? true)) {
      return false;
    }

    if (!(isLaunchable ?? true)) {
      return false;
    }

    if (isRebootRequired ?? false) {
      return false;
    }

    return true;
  }
}
