// Copyright 2019 The Chromium 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, ProcessResult;
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 'package:process/process.dart';

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

class MockPlatform extends Mock implements Platform {
  @override
  Map<String, String> environment = <String, String>{};
}
class MockProcessManager extends Mock implements ProcessManager {}
class MockProcessResult extends Mock implements ProcessResult {}

void main() {
  const String programFilesPath = r'C:\Program Files (x86)';
  const String visualStudioPath = programFilesPath + r'\Microsoft Visual Studio\2017\Community';
  const String vcvarsPath = visualStudioPath + r'\VC\Auxiliary\Build\vcvars64.bat';
  const String vswherePath = programFilesPath + r'\Microsoft Visual Studio\Installer\vswhere.exe';

  final MockPlatform windowsPlatform = MockPlatform()
      ..environment['PROGRAMFILES(X86)'] = r'C:\Program Files (x86)\';
  MockProcessManager mockProcessManager;
  final MemoryFileSystem memoryFilesystem = MemoryFileSystem(style: FileSystemStyle.windows);

  // 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 version of a response that doesn't include certain installation status
  // information that might be missing in older Visual Studio versions.
  const Map<String, dynamic> _missingStatusResponse = <String, dynamic>{
    'installationPath': visualStudioPath,
    'displayName': 'Visual Studio Community 2017',
    'installationVersion': '15.9.28307.665',
    'catalog': <String, dynamic>{
      'productDisplayVersion': '15.9.12',
    },
  };

  // Arguments for a vswhere query to search for an installation with the required components.
  const List<String> _requiredComponents = <String>[
    'Microsoft.Component.MSBuild',
    'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
    'Microsoft.VisualStudio.Component.Windows10SDK.17763',
  ];

  // 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([
    List<String> requiredComponents,
    List<String> additionalArguments,
    Map<String, dynamic> response,
  ]) {
    fs.file(vswherePath).createSync(recursive: true);
    fs.file(vcvarsPath).createSync(recursive: true);

    final MockProcessResult result = MockProcessResult();
    when(result.exitCode).thenReturn(0);

    final String finalResponse =
        json.encode(<Map<String, dynamic>>[response]);
    when<String>(result.stdout).thenReturn(finalResponse);
    when<String>(result.stderr).thenReturn('');
    final List<String> requirementArguments = requiredComponents == null
        ? <String>[]
        : <String>['-requires', ...requiredComponents];
    when(mockProcessManager.runSync(
      <String>[
        vswherePath,
        '-format',
        'json',
        '-utf8',
        '-latest',
        ...?additionalArguments,
        ...?requirementArguments,
      ],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenAnswer((Invocation invocation) {
      return result;
    });
  }

  // Sets whether or not a vswhere query with the required components will
  // return an installation.
  void setMockCompatibleVisualStudioInstallation(Map<String, dynamic>response) {
    setMockVswhereResponse(_requiredComponents, null, response);
  }

  // Sets whether or not a vswhere query with the required components will
  // return a pre-release installation.
  void setMockPrereleaseVisualStudioInstallation(Map<String, dynamic>response) {
    setMockVswhereResponse(_requiredComponents, <String>['-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) {
    setMockVswhereResponse(null, <String>['-prerelease', '-all'], response);
  }

  group('Visual Studio', () {
    VisualStudio visualStudio;

    setUp(() {
      mockProcessManager = MockProcessManager();
    });

    testUsingContext('isInstalled returns false when vswhere is missing', () {
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenThrow(const ProcessException('vswhere', <String>[]));

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('vcvarsPath returns null when vswhere is missing', () {
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenThrow(const ProcessException('vswhere', <String>[]));

      visualStudio = VisualStudio();
      expect(visualStudio.vcvarsPath, isNull);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isInstalled returns false when vswhere returns non-zero', () {

      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenThrow(const ProcessException('vswhere', <String>[]));

      final MockProcessResult result = MockProcessResult();
      when(result.exitCode).thenReturn(1);
      when(mockProcessManager.runSync(
        any,
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((Invocation invocation) {
        return result;
      });
      when<String>(result.stdout).thenReturn('');
      when<String>(result.stderr).thenReturn('');

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('VisualStudio getters return the right values if no installation is found', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(null);

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, 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);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('necessaryComponentDescriptions suggest the right VS tools on major version 15', () {

      visualStudio = VisualStudio();
      final String toolsString = visualStudio.necessaryComponentDescriptions(15)[1];
      expect(toolsString.contains('v141'), true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('necessaryComponentDescriptions suggest the right VS tools on major version != 15', () {

      visualStudio = VisualStudio();
      final String toolsString = visualStudio.necessaryComponentDescriptions(16)[1];
      expect(toolsString.contains('v142'), true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isInstalled returns true even with missing status information', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(_missingStatusResponse);

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isInstalled returns true when VS is present but missing components', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(_defaultResponse);

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isInstalled returns true when a prerelease version of VS is present', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(null);

      final Map<String, dynamic> response = Map<String, dynamic>.from(_defaultResponse)
        ..['isPrerelease'] = true;
      setMockPrereleaseVisualStudioInstallation(response);

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isPrerelease, true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isComplete returns false when an incomplete installation is found', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);

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

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isComplete, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isLaunchable returns false if the installation can\'t be launched', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);

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

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isLaunchable, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('isRebootRequired returns true if the installation needs a reboot', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);

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

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
      expect(visualStudio.isRebootRequired, true);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });


    testUsingContext('hasNecessaryComponents returns false when VS is present but missing components', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(_defaultResponse);

      visualStudio = VisualStudio();
      expect(visualStudio.hasNecessaryComponents, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('vcvarsPath returns null when VS is present but missing components', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(_defaultResponse);

      visualStudio = VisualStudio();
      expect(visualStudio.vcvarsPath, isNull);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('vcvarsPath returns null when VS is present but with require components but installation is faulty', () {
      final Map<String, dynamic> response = Map<String, dynamic>.from(_defaultResponse)
        ..['isRebootRequired'] = true;
      setMockCompatibleVisualStudioInstallation(response);
      setMockPrereleaseVisualStudioInstallation(null);

      visualStudio = VisualStudio();
      expect(visualStudio.vcvarsPath, isNull);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('hasNecessaryComponents returns false when VS is present with required components but installation is faulty', () {
      final Map<String, dynamic> response = Map<String, dynamic>.from(_defaultResponse)
        ..['isRebootRequired'] = true;
      setMockCompatibleVisualStudioInstallation(response);
      setMockPrereleaseVisualStudioInstallation(null);

      visualStudio = VisualStudio();
      expect(visualStudio.hasNecessaryComponents, false);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('VS metadata is available when VS is present, even if missing components', () {
      setMockCompatibleVisualStudioInstallation(null);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(_defaultResponse);

      visualStudio = VisualStudio();
      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'));
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('Everything returns good values when VS is present with all components', () {
      setMockCompatibleVisualStudioInstallation(_defaultResponse);
      setMockPrereleaseVisualStudioInstallation(null);
      setMockAnyVisualStudioInstallation(null);

      visualStudio = VisualStudio();
      expect(visualStudio.isInstalled, true);
      expect(visualStudio.hasNecessaryComponents, true);
      expect(visualStudio.vcvarsPath, equals(vcvarsPath));
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('Metadata is for compatible version when latest is missing components', () {
      // 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);
      setMockPrereleaseVisualStudioInstallation(null);
      // 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);

      visualStudio = VisualStudio();
      expect(visualStudio.displayName, equals('Visual Studio Community 2017'));
      expect(visualStudio.displayVersion, equals('15.9.12'));
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFilesystem,
      Platform: () => windowsPlatform,
      ProcessManager: () => mockProcessManager,
    });
  });
}
