// 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 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter_devicelab/common.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;

TaskFunction dartPluginRegistryTest({
  String deviceIdOverride,
  Map<String, String> environment,
}) {
  final Directory tempDir = Directory.systemTemp
      .createTempSync('flutter_devicelab_dart_plugin_test.');
  return () async {
    try {
      section('Create implementation plugin');
      await inDirectory(tempDir, () async {
        await flutter(
          'create',
          options: <String>[
            '--template=plugin',
            '--org',
            'io.flutter.devicelab',
            '--platforms',
            'macos',
            'plugin_platform_implementation',
          ],
          environment: environment,
        );
      });

      final File pluginMain = File(path.join(
        tempDir.absolute.path,
        'plugin_platform_implementation',
        'lib',
        'plugin_platform_implementation.dart',
      ));
      if (!pluginMain.existsSync()) {
        return TaskResult.failure('${pluginMain.path} does not exist');
      }

      // Patch plugin main dart file.
      await pluginMain.writeAsString('''
class PluginPlatformInterfaceMacOS {
  static void registerWith() {
    print('PluginPlatformInterfaceMacOS.registerWith() was called');
  }
}
''', flush: true);

      // Patch plugin main pubspec file.
      final File pluginImplPubspec = File(path.join(
        tempDir.absolute.path,
        'plugin_platform_implementation',
        'pubspec.yaml',
      ));
      String pluginImplPubspecContent = await pluginImplPubspec.readAsString();
      pluginImplPubspecContent = pluginImplPubspecContent.replaceFirst(
        '        pluginClass: PluginPlatformImplementationPlugin',
        '        pluginClass: PluginPlatformImplementationPlugin\n'
            '        dartPluginClass: PluginPlatformInterfaceMacOS\n',
      );
      pluginImplPubspecContent = pluginImplPubspecContent.replaceFirst(
          '    platforms:\n',
          '    implements: plugin_platform_interface\n'
              '    platforms:\n');
      await pluginImplPubspec.writeAsString(pluginImplPubspecContent,
          flush: true);

      section('Create interface plugin');
      await inDirectory(tempDir, () async {
        await flutter(
          'create',
          options: <String>[
            '--template=plugin',
            '--org',
            'io.flutter.devicelab',
            '--platforms',
            'macos',
            'plugin_platform_interface',
          ],
          environment: environment,
        );
      });
      final File pluginInterfacePubspec = File(path.join(
        tempDir.absolute.path,
        'plugin_platform_interface',
        'pubspec.yaml',
      ));
      String pluginInterfacePubspecContent =
          await pluginInterfacePubspec.readAsString();
      pluginInterfacePubspecContent =
          pluginInterfacePubspecContent.replaceFirst(
              '        pluginClass: PluginPlatformInterfacePlugin',
              '        default_package: plugin_platform_implementation\n');
      pluginInterfacePubspecContent =
          pluginInterfacePubspecContent.replaceFirst(
              'dependencies:',
              'dependencies:\n'
                  '  plugin_platform_implementation:\n'
                  '    path: ../plugin_platform_implementation\n');
      await pluginInterfacePubspec.writeAsString(pluginInterfacePubspecContent,
          flush: true);

      section('Create app');

      await inDirectory(tempDir, () async {
        await flutter(
          'create',
          options: <String>[
            '--template=app',
            '--org',
            'io.flutter.devicelab',
            '--platforms',
            'macos',
            'app',
          ],
          environment: environment,
        );
      });

      final File appPubspec = File(path.join(
        tempDir.absolute.path,
        'app',
        'pubspec.yaml',
      ));
      String appPubspecContent = await appPubspec.readAsString();
      appPubspecContent = appPubspecContent.replaceFirst(
          'dependencies:',
          'dependencies:\n'
              '  plugin_platform_interface:\n'
              '    path: ../plugin_platform_interface\n');
      await appPubspec.writeAsString(appPubspecContent, flush: true);

      section('Flutter run for macos');

      await inDirectory(path.join(tempDir.path, 'app'), () async {
        final Process run = await startProcess(
          path.join(flutterDirectory.path, 'bin', 'flutter'),
          flutterCommandArgs('run', <String>['-d', 'macos', '-v']),
          environment: null,
        );
        Completer<void> registryExecutedCompleter = Completer<void>();
        final StreamSubscription<void> subscription = run.stdout
            .transform<String>(utf8.decoder)
            .transform<String>(const LineSplitter())
            .listen((String line) {
          if (line.contains(
              'PluginPlatformInterfaceMacOS.registerWith() was called')) {
            registryExecutedCompleter.complete();
          }
          print('stdout: $line');
        });

        section('Wait for registry execution');
        await registryExecutedCompleter.future;

        // Hot restart.
        run.stdin.write('R');
        registryExecutedCompleter = Completer<void>();

        section('Wait for registry execution after hot restart');
        await registryExecutedCompleter.future;

        unawaited(subscription.cancel());
        run.kill();
      });
      return TaskResult.success(null);
    } finally {
      rmTree(tempDir);
    }
  };
}
