// 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 '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../convert.dart';

VisualStudio get visualStudio => context.get<VisualStudio>();

/// Encapsulates information about the installed copy of Visual Studio, if any.
class VisualStudio {
  /// True if a sufficiently recent version of Visual Studio is installed.
  ///
  /// 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.isNotEmpty;

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

  /// The name of the Visual Studio install.
  ///
  /// For instance: "Visual Studio Community 2017".
  String get displayName => _bestVisualStudioDetails[_displayNameKey] as String;

  /// The user-friendly version number of the Visual Studio install.
  ///
  /// For instance: "15.4.0".
  String get displayVersion {
    if (_bestVisualStudioDetails[_catalogKey] == null) {
      return null;
    }
    return _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey] as String;
  }

  /// The directory where Visual Studio is installed.
  String get installLocation => _bestVisualStudioDetails[_installationPathKey] as String;

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

  // 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.isEmpty) {
      return false;
    }
    return _bestVisualStudioDetails[_isCompleteKey] as bool ?? true;
  }

  /// True if Visual Studio is launchable.
  ///
  /// False if installation is not found.
  bool get isLaunchable {
    if (_bestVisualStudioDetails.isEmpty) {
      return false;
    }
    return _bestVisualStudioDetails[_isLaunchableKey] as bool ?? true;
  }

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

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

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

  /// The names of the components within the workload that must be installed.
  ///
  /// If there is an existing Visual Studio installation, the major version
  /// should be provided here, as the descriptions of some components differ
  /// from version to version.
  List<String> necessaryComponentDescriptions([int visualStudioMajorVersion]) {
    return _requiredComponents(visualStudioMajorVersion).values.toList();
  }

  /// The path to vcvars64.bat, or null if no Visual Studio installation has
  /// the components necessary to build.
  String get vcvarsPath {
    final Map<String, dynamic> details = _usableVisualStudioDetails;
    if (details.isEmpty) {
      return null;
    }
    return fs.path.join(
      _usableVisualStudioDetails[_installationPathKey] as String,
      'VC',
      'Auxiliary',
      'Build',
      'vcvars64.bat',
    );
  }

  /// 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.
  final String _vswherePath = fs.path.join(
    platform.environment['PROGRAMFILES(X86)'],
    'Microsoft Visual Studio',
    'Installer',
    'vswhere.exe',
  );

  /// 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 visualStudioMajorVersion]) {
    // The description of the C++ toolchain required by the template. The
    // component name is significantly different in different versions.
    // Default to the latest known description, but use a specific string
    // if a known older version is requested.
    String cppToolchainDescription = 'MSVC v142 - VS 2019 C++ x64/x86 build tools';
    if (visualStudioMajorVersion == 15) {
      cppToolchainDescription = 'VC++ 2017 version 15.9 v14.## latest v141 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 versions, install the latest one';
    return <String, String>{
      // The MSBuild tool and related command-line toolchain.
      'Microsoft.Component.MSBuild': 'MSBuild',
      // The C++ toolchain required by the template.
      'Microsoft.VisualStudio.Component.VC.Tools.x86.x64': cppToolchainDescription,
      // The Windows SDK version used by the template.
      'Microsoft.VisualStudio.Component.Windows10SDK.17763':
          'Windows 10 SDK (10.0.17763.0)',
    };
  }

  // Keys in a VS details dictionary returned from vswhere.

  /// The root directory of the Visual Studio installation.
  static const String _installationPathKey = 'installationPath';

  /// The user-friendly name of the installation.
  static const String _displayNameKey = 'displayName';

  /// The complete version.
  static const String _fullVersionKey = 'installationVersion';

  /// Keys for the status of the installation.
  static const String _isCompleteKey = 'isComplete';
  static const String _isLaunchableKey = 'isLaunchable';
  static const String _isRebootRequiredKey = 'isRebootRequired';

  /// The 'catalog' entry containing more details.
  static const String _catalogKey = 'catalog';

  /// The key for a pre-release version.
  static const String _isPrereleaseKey = 'isPrerelease';

  /// The user-friendly version.
  ///
  /// This key is under the 'catalog' entry.
  static const String _catalogDisplayVersionKey = 'productDisplayVersion';

  /// vswhere argument keys
  static const String _prereleaseKey = '-prerelease';

  /// Returns the details dictionary for the newest version of Visual Studio
  /// that includes all of [requiredComponents], if there is one.
  Map<String, dynamic> _visualStudioDetails(
      {Iterable<String> requiredComponents, List<String> additionalArguments}) {
    final List<String> requirementArguments = requiredComponents == null
        ? <String>[]
        : <String>['-requires', ...requiredComponents];
    try {
      final List<String> defaultArguments = <String>[
        '-format', 'json',
        '-utf8',
        '-latest',
      ];
      final RunResult whereResult = processUtils.runSync(<String>[
        _vswherePath,
        ...defaultArguments,
        ...?additionalArguments,
        ...?requirementArguments,
      ]);
      if (whereResult.exitCode == 0) {
        final List<Map<String, dynamic>> installations =
            (json.decode(whereResult.stdout) as List<dynamic>).cast<Map<String, dynamic>>();
        if (installations.isNotEmpty) {
          return installations[0];
        }
      }
    } on ArgumentError {
      // Thrown if vswhere doesnt' exist; ignore and return null below.
    } on ProcessException {
      // Ignored, return null below.
    } on FormatException {
      // may be thrown if invalid JSON is returned.
    }
    return null;
  }

  /// Checks if the given installation has issues that the user must resolve.
  ///
  /// Returns false if the required information is missing since older versions
  /// of Visual Studio might not include them.
  bool installationHasIssues(Map<String, dynamic>installationDetails) {
    assert(installationDetails != null);
    if (installationDetails[_isCompleteKey] != null && !(installationDetails[_isCompleteKey] as bool)) {
      return true;
    }

    if (installationDetails[_isLaunchableKey] != null && !(installationDetails[_isLaunchableKey] as bool)) {
      return true;
    }

    if (installationDetails[_isRebootRequiredKey] != null && installationDetails[_isRebootRequiredKey] as bool) {
      return true;
    }

    return false;
  }

  /// Returns the details dictionary for the latest version of Visual Studio
  /// that has all required components, or {} if there is no such installation.
  ///
  /// If no installation is found, the cached VS details are set to an empty map
  /// to avoid repeating vswhere queries that have already not found an installation.
  Map<String, dynamic> _cachedUsableVisualStudioDetails;
  Map<String, dynamic> get _usableVisualStudioDetails {
    if (_cachedUsableVisualStudioDetails != null) {
      return _cachedUsableVisualStudioDetails;
    }
    Map<String, dynamic> visualStudioDetails =
        _visualStudioDetails(requiredComponents: _requiredComponents().keys);
    // If a stable version is not found, try searching for a pre-release version.
    visualStudioDetails ??= _visualStudioDetails(
        requiredComponents: _requiredComponents().keys,
        additionalArguments: <String>[_prereleaseKey]);

    if (visualStudioDetails != null) {
      if (installationHasIssues(visualStudioDetails)) {
        _cachedAnyVisualStudioDetails = visualStudioDetails;
      } else {
        _cachedUsableVisualStudioDetails = visualStudioDetails;
      }
    }
    _cachedUsableVisualStudioDetails ??= <String, dynamic>{};
    return _cachedUsableVisualStudioDetails;
  }

  /// Returns the details dictionary of the latest version of Visual Studio,
  /// regardless of components, or {} if no such installation is found.
  ///
  /// If no installation is found, the cached
  /// VS details are set to an empty map to avoid repeating vswhere queries that
  /// have already not found an installation.
  Map<String, dynamic> _cachedAnyVisualStudioDetails;
  Map<String, dynamic> get _anyVisualStudioDetails {
    // Search for all types of installations.
    _cachedAnyVisualStudioDetails ??= _visualStudioDetails(
        additionalArguments: <String>[_prereleaseKey, '-all']);
    // Add a sentinel empty value to avoid querying vswhere again.
    _cachedAnyVisualStudioDetails ??= <String, dynamic>{};
    return _cachedAnyVisualStudioDetails;
  }

  /// Returns the details dictionary 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 (if any).
  Map<String, dynamic> get _bestVisualStudioDetails {
    if (_usableVisualStudioDetails.isNotEmpty) {
      return _usableVisualStudioDetails;
    }
    return _anyVisualStudioDetails;
  }
}
