// 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.

// @dart = 2.8

import 'package:meta/meta.dart';

import '../base/file_system.dart';
import '../base/platform.dart';
import '../base/utils.dart';
import '../base/version.dart';
import '../convert.dart';
import '../doctor.dart';

// Include VS Code insiders (useful for debugging).
const bool _includeInsiders = false;

const String extensionIdentifier = 'Dart-Code.flutter';
const String extensionMarketplaceUrl =
  'https://marketplace.visualstudio.com/items?itemName=$extensionIdentifier';

class VsCode {
  VsCode._(this.directory, this.extensionDirectory, { Version version, this.edition, @required FileSystem fileSystem})
      : version = version ?? Version.unknown {

    if (!fileSystem.isDirectorySync(directory)) {
      _validationMessages.add(ValidationMessage.error('VS Code not found at $directory'));
      return;
    } else {
      _validationMessages.add(ValidationMessage('VS Code at $directory'));
    }

    // If the extensions directory doesn't exist at all, the listSync()
    // below will fail, so just bail out early.
    const ValidationMessage notInstalledMessage = ValidationMessage(
      'Flutter extension can be installed from:',
      contextUrl: extensionMarketplaceUrl,
    );
    if (!fileSystem.isDirectorySync(extensionDirectory)) {
      _validationMessages.add(notInstalledMessage);
      return;
    }

    // Check for presence of extension.
    final String extensionIdentifierLower = extensionIdentifier.toLowerCase();
    final Iterable<FileSystemEntity> extensionDirs = fileSystem
        .directory(extensionDirectory)
        .listSync()
        .whereType<Directory>()
        .where((Directory d) => d.basename.toLowerCase().startsWith(extensionIdentifierLower));

    if (extensionDirs.isNotEmpty) {
      final FileSystemEntity extensionDir = extensionDirs.first;

      _extensionVersion = Version.parse(
          extensionDir.basename.substring('$extensionIdentifier-'.length));
      _validationMessages.add(ValidationMessage('Flutter extension version $_extensionVersion'));
    } else {
      _validationMessages.add(notInstalledMessage);
    }
  }

  factory VsCode.fromDirectory(
    String installPath,
    String extensionDirectory, {
    String edition,
    @required FileSystem fileSystem,
  }) {
    final String packageJsonPath =
        fileSystem.path.join(installPath, 'resources', 'app', 'package.json');
    final String versionString = _getVersionFromPackageJson(packageJsonPath, fileSystem);
    Version version;
    if (versionString != null) {
      version = Version.parse(versionString);
    }
    return VsCode._(installPath, extensionDirectory, version: version, edition: edition, fileSystem: fileSystem);
  }

  final String directory;
  final String extensionDirectory;
  final Version version;
  final String edition;

  Version _extensionVersion;
  final List<ValidationMessage> _validationMessages = <ValidationMessage>[];

  String get productName => 'VS Code' + (edition != null ? ', $edition' : '');

  Iterable<ValidationMessage> get validationMessages => _validationMessages;

  static List<VsCode> allInstalled(
    FileSystem fileSystem,
    Platform platform,
  ) {
    if (platform.isMacOS) {
      return _installedMacOS(fileSystem, platform);
    }
    if (platform.isWindows) {
      return _installedWindows(fileSystem, platform);
    }
    if (platform.isLinux) {
      return _installedLinux(fileSystem, platform);
    }
    // VS Code isn't supported on the other platforms.
    return <VsCode>[];
  }

  // macOS:
  //   /Applications/Visual Studio Code.app/Contents/
  //   /Applications/Visual Studio Code - Insiders.app/Contents/
  //   $HOME/Applications/Visual Studio Code.app/Contents/
  //   $HOME/Applications/Visual Studio Code - Insiders.app/Contents/
  // macOS Extensions:
  //   $HOME/.vscode/extensions
  //   $HOME/.vscode-insiders/extensions
  static List<VsCode> _installedMacOS(FileSystem fileSystem, Platform platform) {
    return _findInstalled(<_VsCodeInstallLocation>[
      _VsCodeInstallLocation(
        fileSystem.path.join('/Applications', 'Visual Studio Code.app', 'Contents'),
        '.vscode',
      ),
      _VsCodeInstallLocation(
        fileSystem.path.join(
          FileSystemUtils(fileSystem: fileSystem, platform: platform).homeDirPath,
          'Applications',
          'Visual Studio Code.app',
          'Contents',
        ),
        '.vscode',
      ),
      _VsCodeInstallLocation(
        fileSystem.path.join('/Applications', 'Visual Studio Code - Insiders.app', 'Contents'),
        '.vscode-insiders',
        isInsiders: true,
      ),
      _VsCodeInstallLocation(
        fileSystem.path.join(
          FileSystemUtils(fileSystem: fileSystem, platform: platform).homeDirPath,
          'Applications',
          'Visual Studio Code - Insiders.app',
          'Contents',
        ),
        '.vscode-insiders',
        isInsiders: true,
      ),
    ], fileSystem, platform);
  }

  // Windows:
  //   $programfiles(x86)\Microsoft VS Code
  //   $programfiles(x86)\Microsoft VS Code Insiders
  // User install:
  //   $localappdata\Programs\Microsoft VS Code
  //   $localappdata\Programs\Microsoft VS Code Insiders
  // TODO(dantup): Confirm these are correct for 64bit
  //   $programfiles\Microsoft VS Code
  //   $programfiles\Microsoft VS Code Insiders
  // Windows Extensions:
  //   $HOME/.vscode/extensions
  //   $HOME/.vscode-insiders/extensions
  static List<VsCode> _installedWindows(
    FileSystem fileSystem,
    Platform platform,
  ) {
    final String progFiles86 = platform.environment['programfiles(x86)'];
    final String progFiles = platform.environment['programfiles'];
    final String localAppData = platform.environment['localappdata'];

    final List<_VsCodeInstallLocation> searchLocations = <_VsCodeInstallLocation>[
      if (localAppData != null)
        _VsCodeInstallLocation(
          fileSystem.path.join(localAppData, r'Programs\Microsoft VS Code'),
          '.vscode',
        ),
      if (progFiles86 != null)
        ...<_VsCodeInstallLocation>[
          _VsCodeInstallLocation(
            fileSystem.path.join(progFiles86, 'Microsoft VS Code'),
            '.vscode',
            edition: '32-bit edition',
          ),
          _VsCodeInstallLocation(
            fileSystem.path.join(progFiles86, 'Microsoft VS Code Insiders'),
            '.vscode-insiders',
            edition: '32-bit edition',
            isInsiders: true,
          ),
        ],
      if (progFiles != null)
        ...<_VsCodeInstallLocation>[
          _VsCodeInstallLocation(
            fileSystem.path.join(progFiles, 'Microsoft VS Code'),
            '.vscode',
            edition: '64-bit edition',
          ),
          _VsCodeInstallLocation(
            fileSystem.path.join(progFiles, 'Microsoft VS Code Insiders'),
            '.vscode-insiders',
            edition: '64-bit edition',
            isInsiders: true,
          ),
        ],
      if (localAppData != null)
        _VsCodeInstallLocation(
          fileSystem.path.join(localAppData, r'Programs\Microsoft VS Code Insiders'),
          '.vscode-insiders',
          isInsiders: true,
        ),
    ];
    return _findInstalled(searchLocations, fileSystem, platform);
  }

  // Linux:
  //   /usr/share/code/bin/code
  //   /usr/share/code-insiders/bin/code-insiders
  // Linux Extensions:
  //   $HOME/.vscode/extensions
  //   $HOME/.vscode-insiders/extensions
  static List<VsCode> _installedLinux(FileSystem fileSystem, Platform platform) {
    return _findInstalled(<_VsCodeInstallLocation>[
      const _VsCodeInstallLocation('/usr/share/code', '.vscode'),
      const _VsCodeInstallLocation(
        '/usr/share/code-insiders',
        '.vscode-insiders',
        isInsiders: true,
      ),
    ], fileSystem, platform);
  }

  static List<VsCode> _findInstalled(
    List<_VsCodeInstallLocation> allLocations,
    FileSystem fileSystem,
    Platform platform,
  ) {
    final Iterable<_VsCodeInstallLocation> searchLocations =
      _includeInsiders
        ? allLocations
        : allLocations.where((_VsCodeInstallLocation p) => p.isInsiders != true);

    final List<VsCode> results = <VsCode>[];

    for (final _VsCodeInstallLocation searchLocation in searchLocations) {
      if (fileSystem.isDirectorySync(searchLocation.installPath)) {
        final String extensionDirectory = fileSystem.path.join(
          FileSystemUtils(fileSystem: fileSystem, platform: platform).homeDirPath,
          searchLocation.extensionsFolder,
          'extensions',
        );
        results.add(VsCode.fromDirectory(
          searchLocation.installPath,
          extensionDirectory,
          edition: searchLocation.edition,
          fileSystem: fileSystem,
        ));
      }
    }

    return results;
  }

  @override
  String toString() =>
      'VS Code ($version)${_extensionVersion != Version.unknown ? ', Flutter ($_extensionVersion)' : ''}';

  static String _getVersionFromPackageJson(String packageJsonPath, FileSystem fileSystem) {
    if (!fileSystem.isFileSync(packageJsonPath)) {
      return null;
    }
    final String jsonString = fileSystem.file(packageJsonPath).readAsStringSync();
    try {
      final Map<String, dynamic> jsonObject = castStringKeyedMap(json.decode(jsonString));
      return jsonObject['version'] as String;
    } on FormatException {
      return null;
    }
  }
}

class _VsCodeInstallLocation {
  const _VsCodeInstallLocation(
    this.installPath,
    this.extensionsFolder, {
    this.edition,
    bool isInsiders
  }) : isInsiders = isInsiders ?? false;

  final String installPath;
  final String extensionsFolder;
  final String edition;
  final bool isInsiders;
}
