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

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

/// A parser for the Intellij and Android Studio plugin JAR files.
///
/// This searches on the provided plugin path for a JAR archive, then
/// unzips it to parse the META-INF/plugin.xml for version information.
///
/// In particular, the Intellij Flutter plugin has a different structure depending on the version.
///
/// For flutter-intellij plugin v49 or lower:
///   flutter-intellij/lib/flutter-intellij.jar ( includes META-INF/plugin.xml )
///
/// For flutter-intellij plugin v50 or higher and for Intellij 2020.2:
///   flutter-intellij/lib/flutter-intellij-X.Y.Z.jar
///                        flutter-idea-X.Y.Z.jar ( includes META-INF/plugin.xml )
///                        flutter-studio-X.Y.Z.jar
///
/// For flutter-intellij plugin v50 or higher and for Intellij 2020.3:
///   flutter-intellij/lib/flutter-intellij-X.Y.Z.jar
///                        flutter-idea-X.Y.Z.jar ( includes META-INF/plugin.xml )
///
/// where X.Y.Z is the version number.
///
/// Intellij Flutter plugin's files can be found here:
///   https://plugins.jetbrains.com/plugin/9212-flutter/versions/stable
///
/// See also:
///   * [IntellijValidator], the validator base class that uses this to check
///     plugin versions.
class IntelliJPlugins {
  IntelliJPlugins(this.pluginsPath, {
    @required FileSystem fileSystem
  }) : _fileSystem = fileSystem;

  final FileSystem _fileSystem;
  final String pluginsPath;

  static final Version kMinFlutterPluginVersion = Version(16, 0, 0);
  static const String kIntellijDartPluginUrl = 'https://plugins.jetbrains.com/plugin/6351-dart';
  static const String kIntellijFlutterPluginUrl = 'https://plugins.jetbrains.com/plugin/9212-flutter';

  void validatePackage(
    List<ValidationMessage> messages,
    List<String> packageNames,
    String title,
    String url, {
    Version minVersion,
  }) {
    for (final String packageName in packageNames) {
      if (!_hasPackage(packageName)) {
        continue;
      }

      final String versionText = _readPackageVersion(packageName);
      final Version version = Version.parse(versionText);
      if (version != null && minVersion != null && version < minVersion) {
        messages.add(ValidationMessage.error(
          '$title plugin version $versionText - the recommended minimum version is $minVersion'),
        );
      } else {
        messages.add(ValidationMessage(
          '$title plugin ${version != null ? "version $version" : "installed"}'),
        );
      }
      return;
    }
    messages.add(ValidationMessage(
      '$title plugin can be installed from:',
      contextUrl: url,
    ));
  }

  bool _hasPackage(String packageName) {
    final String packagePath = _fileSystem.path.join(pluginsPath, packageName);
    if (packageName.endsWith('.jar')) {
      return _fileSystem.isFileSync(packagePath);
    }
    return _fileSystem.isDirectorySync(packagePath);
  }

  ArchiveFile _findPluginXml(String packageName) {
    final List<File> mainJarFileList = <File>[];
    if (packageName.endsWith('.jar')) {
      // package exists (checked in _hasPackage)
      mainJarFileList.add(_fileSystem.file(_fileSystem.path.join(pluginsPath, packageName)));
    } else {
      final String packageLibPath =
          _fileSystem.path.join(pluginsPath, packageName, 'lib');
      if (!_fileSystem.isDirectorySync(packageLibPath)) {
        return null;
      }
      // Collect the files with a file suffix of .jar/.zip that contains the plugin.xml file
      final List<File> pluginJarFiles = _fileSystem
          .directory(_fileSystem.path.join(pluginsPath, packageName, 'lib'))
          .listSync()
          .whereType<File>()
          .where((File file) {
            final String fileExt= _fileSystem.path.extension(file.path);
            return fileExt == '.jar' || fileExt == '.zip';
          })
          .toList();

      if (pluginJarFiles.isEmpty) {
        return null;
      }
      // Prefer file with the same suffix as the package name
      pluginJarFiles.sort((File a, File b) {
        final bool aStartWithPackageName =
            a.basename.toLowerCase().startsWith(packageName.toLowerCase());
        final bool bStartWithPackageName =
            b.basename.toLowerCase().startsWith(packageName.toLowerCase());
        if (bStartWithPackageName != aStartWithPackageName) {
          return bStartWithPackageName ? 1 : -1;
        }
        return a.basename.length - b.basename.length;
      });
      mainJarFileList.addAll(pluginJarFiles);
    }

    for (final File file in mainJarFileList) {
      final Archive archive = ZipDecoder().decodeBytes(file.readAsBytesSync());
      final ArchiveFile archiveFile = archive.findFile('META-INF/plugin.xml');
      if (archiveFile != null) {
        return archiveFile;
      }
    }
    return null;
  }

  String _readPackageVersion(String packageName) {
    try {
      final ArchiveFile archiveFile = _findPluginXml(packageName);
      if (archiveFile == null) {
        return null;
      }
      final String content = utf8.decode(archiveFile.content as List<int>);
      const String versionStartTag = '<version>';
      final int start = content.indexOf(versionStartTag);
      final int end = content.indexOf('</version>', start);
      return content.substring(start + versionStartTag.length, end);
    } on ArchiveException {
      return null;
    }
  }
}
