// 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 '../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;
}
