// 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:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/dart_plugin_registrant.dart';
import 'package:flutter_tools/src/project.dart';

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

const String _kEmptyPubspecFile = '''
name: path_provider_example

dependencies:
  flutter:
    sdk: flutter
''';

const String _kEmptyPackageJson = '''
{
  "configVersion": 2,
  "packages": [
     {
      "name": "path_provider_example",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''';

const String _kSamplePackageJson = '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "path_provider_linux",
      "rootUri": "/path_provider_linux",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    },
    {
      "name": "path_provider_example",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''';

const String _kSamplePackagesFile = '''
path_provider_linux:/path_provider_linux/lib/
path_provider_example:lib/
''';

const String _kSamplePubspecFile = '''
name: path_provider_example
description: Demonstrates how to use the path_provider plugin.

dependencies:
  flutter:
    sdk: flutter
  path_provider_linux: 1.0.0
''';

const String _kSamplePluginPubspec = '''
name: path_provider_linux
description: linux implementation of the path_provider plugin
// version: 2.0.1
// homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux

flutter:
  plugin:
    implements: path_provider
    platforms:
      linux:
        dartPluginClass: PathProviderLinux
        pluginClass: none

environment:
  sdk: '>=3.0.0-0 <4.0.0'
  flutter: ">=1.20.0"
''';

void main() {

  group('Dart plugin registrant' , () {
    late FileSystem fileSystem;

    setUp(() {
      fileSystem = MemoryFileSystem.test();
    });

    testWithoutContext('skipped based on environment.generateDartPluginRegistry',
        () async {
      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        artifacts: Artifacts.test(),
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
      );

      expect(const DartPluginRegistrantTarget().canSkip(environment), isTrue);

      final Environment environment2 = Environment.test(
          fileSystem.currentDirectory,
          artifacts: Artifacts.test(),
          fileSystem: fileSystem,
          logger: BufferLogger.test(),
          processManager: FakeProcessManager.any(),
          generateDartPluginRegistry: true);

      expect(const DartPluginRegistrantTarget().canSkip(environment2), isFalse);
    });

    testWithoutContext('skipped based on platform', () async {
      const Map<String, bool> canSkip = <String, bool>{
        'darwin-x64': false,
        'linux-x64': false,
        'linux-arm64': false,
        'windows-x64': false,
        'web-javascript': true,
        'ios': false,
        'android': false,
        'fuchsia-arm64': true,
        'fuchsia-x64': true,
      };

      for (final String targetPlatform in canSkip.keys) {
        expect(
          const DartPluginRegistrantTarget().canSkip(
            Environment.test(
              fileSystem.currentDirectory,
              artifacts: Artifacts.test(),
              fileSystem: fileSystem,
              logger: BufferLogger.test(),
              processManager: FakeProcessManager.any(),
              generateDartPluginRegistry: true,
              defines: <String, String>{
                kTargetPlatform: targetPlatform,
              },
            ),
          ),
          canSkip[targetPlatform],
        );
      }
    });

    testUsingContext("doesn't generate dart_plugin_registrant.dart if there aren't Dart plugins", () async {
      final Directory projectDir = fileSystem.directory('project')..createSync();
      final Environment environment = Environment.test(
          fileSystem.currentDirectory,
          projectDir: projectDir,
          artifacts: Artifacts.test(),
          fileSystem: fileSystem,
          logger: BufferLogger.test(),
          processManager: FakeProcessManager.any(),
          defines: <String, String>{
            kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path,
          },
          generateDartPluginRegistry: true);

      projectDir
          .childDirectory('.dart_tool')
          .childFile('package_config.json')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePackageJson);

      projectDir.childFile('pubspec.yaml').createSync();

      projectDir.childFile('.packages').createSync();

      final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
      await DartPluginRegistrantTarget.test(testProject).build(environment);

      final File generatedMain = projectDir
          .childDirectory('.dart_tool')
          .childDirectory('flutter_build')
          .childFile('dart_plugin_registrant.dart');
      expect(generatedMain.existsSync(), isFalse);
    });

    testUsingContext('regenerates dart_plugin_registrant.dart', () async {
      final Directory projectDir = fileSystem.directory('project')..createSync();
      final Environment environment = Environment.test(
          fileSystem.currentDirectory,
          projectDir: projectDir,
          artifacts: Artifacts.test(),
          fileSystem: fileSystem,
          logger: BufferLogger.test(),
          processManager: FakeProcessManager.any(),
          defines: <String, String>{
            kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path,
          },
          generateDartPluginRegistry: true);

      projectDir
          .childDirectory('.dart_tool')
          .childFile('package_config.json')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePackageJson);

      projectDir.childFile('pubspec.yaml').writeAsStringSync(_kSamplePubspecFile);

      projectDir.childFile('.packages').writeAsStringSync(_kSamplePackagesFile);

      projectDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true);

      environment.fileSystem.currentDirectory
          .childDirectory('path_provider_linux')
          .childFile('pubspec.yaml')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePluginPubspec);

      final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
      await DartPluginRegistrantTarget.test(testProject).build(environment);

      final File generatedMain = projectDir
          .childDirectory('.dart_tool')
          .childDirectory('flutter_build')
          .childFile('dart_plugin_registrant.dart');
      final String mainContent = generatedMain.readAsStringSync();
      expect(
        mainContent,
        equals(
          '//\n'
          '// Generated file. Do not edit.\n'
          '// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n'
          '//\n'
          '\n'
          '// @dart = 2.12\n'
          '\n'
          "import 'dart:io'; // flutter_ignore: dart_io_import.\n"
          "import 'package:path_provider_linux/path_provider_linux.dart';\n"
          '\n'
          "@pragma('vm:entry-point')\n"
          'class _PluginRegistrant {\n'
          '\n'
          "  @pragma('vm:entry-point')\n"
          '  static void register() {\n'
          '    if (Platform.isAndroid) {\n'
          '    } else if (Platform.isIOS) {\n'
          '    } else if (Platform.isLinux) {\n'
          '      try {\n'
          '        PathProviderLinux.registerWith();\n'
          '      } catch (err) {\n'
          '        print(\n'
          "          '`path_provider_linux` threw an error: \$err. '\n"
          "          'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
          '        );\n'
          '      }\n'
          '\n'
          '    } else if (Platform.isMacOS) {\n'
          '    } else if (Platform.isWindows) {\n'
          '    }\n'
          '  }\n'
          '}\n'
        ),
      );
    });

    testUsingContext('removes dart_plugin_registrant.dart if plugins are removed from pubspec.yaml', () async {
      final Directory projectDir = fileSystem.directory('project')..createSync();
      final Environment environment = Environment.test(
          fileSystem.currentDirectory,
          projectDir: projectDir,
          artifacts: Artifacts.test(),
          fileSystem: fileSystem,
          logger: BufferLogger.test(),
          processManager: FakeProcessManager.any(),
          defines: <String, String>{
            kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path,
          },
          generateDartPluginRegistry: true);
      final File config = projectDir
          .childDirectory('.dart_tool')
          .childFile('package_config.json')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePackageJson);

      final File pubspec = projectDir.childFile('pubspec.yaml')..writeAsStringSync(_kSamplePubspecFile);

      final File packages = projectDir.childFile('.packages')..writeAsStringSync(_kSamplePackagesFile);

      environment.fileSystem.currentDirectory
          .childDirectory('path_provider_linux')
          .childFile('pubspec.yaml')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePluginPubspec);

      final File generatedMain = projectDir
          .childDirectory('.dart_tool')
          .childDirectory('flutter_build')
          .childFile('dart_plugin_registrant.dart');

      final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
      await DartPluginRegistrantTarget.test(testProject).build(environment);
      expect(generatedMain.existsSync(), isTrue);

      // Simulate a user removing everything from pubspec.yaml.
      pubspec.writeAsStringSync(_kEmptyPubspecFile);
      packages.writeAsStringSync(_kEmptyPackageJson);
      config.writeAsStringSync(_kEmptyPackageJson);

      await DartPluginRegistrantTarget.test(testProject).build(environment);
      expect(generatedMain.existsSync(), isFalse);
    });

    testUsingContext('target file is outside the current project package', () async {
      final Directory projectDir = fileSystem.directory('project')..createSync();
      final Environment environment = Environment.test(
          fileSystem.currentDirectory,
          projectDir: projectDir,
          artifacts: Artifacts.test(),
          fileSystem: fileSystem,
          logger: BufferLogger.test(),
          processManager: FakeProcessManager.any(),
          defines: <String, String>{
            kTargetFile: fileSystem.directory('root').childFile('external.dart').absolute.path,
          },
          generateDartPluginRegistry: true);

      projectDir
          .childDirectory('.dart_tool')
          .childFile('package_config.json')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePackageJson);

      projectDir.childFile('pubspec.yaml').writeAsStringSync(_kSamplePubspecFile);

      projectDir.childFile('.packages').writeAsStringSync(_kSamplePackagesFile);

      projectDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true);

      environment.fileSystem.currentDirectory
          .childDirectory('path_provider_linux')
          .childFile('pubspec.yaml')
          ..createSync(recursive: true)
          ..writeAsStringSync(_kSamplePluginPubspec);

      final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
      await DartPluginRegistrantTarget.test(testProject).build(environment);

      final File generatedMain = projectDir
          .childDirectory('.dart_tool')
          .childDirectory('flutter_build')
          .childFile('dart_plugin_registrant.dart');

      final String mainContent = generatedMain.readAsStringSync();
      expect(
        mainContent,
        equals(
          '//\n'
          '// Generated file. Do not edit.\n'
          '// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n'
          '//\n'
          '\n'
          '// @dart = 2.12\n'
          '\n'
          "import 'dart:io'; // flutter_ignore: dart_io_import.\n"
          "import 'package:path_provider_linux/path_provider_linux.dart';\n"
          '\n'
          "@pragma('vm:entry-point')\n"
          'class _PluginRegistrant {\n'
          '\n'
          "  @pragma('vm:entry-point')\n"
          '  static void register() {\n'
          '    if (Platform.isAndroid) {\n'
          '    } else if (Platform.isIOS) {\n'
          '    } else if (Platform.isLinux) {\n'
          '      try {\n'
          '        PathProviderLinux.registerWith();\n'
          '      } catch (err) {\n'
          '        print(\n'
          "          '`path_provider_linux` threw an error: \$err. '\n"
          "          'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
          '        );\n'
          '      }\n'
          '\n'
          '    } else if (Platform.isMacOS) {\n'
          '    } else if (Platform.isWindows) {\n'
          '    }\n'
          '  }\n'
          '}\n'
        ),
      );
    });
  });
}
