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

import '../base/file_system.dart';
import '../base/version.dart';
import '../convert.dart';
import '../doctor_validator.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;
    }
  }
}
