// 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 '../framework/devices.dart';
import '../framework/framework.dart';
import '../framework/talkback.dart' hide adbPath;
import '../framework/task_result.dart';
import '../framework/utils.dart';

TaskFunction createChannelsIntegrationTest({String? deviceIdOverride}) {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/channels',
    'integration_test/main_test.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createPlatformInteractionTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/platform_interaction',
    'lib/main.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createFlavorsTest({
  Map<String, String>? environment,
  List<String>? extraOptions,
  String? deviceIdOverride,
}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/flavors',
    'lib/main.dart',
    extraOptions: extraOptions ?? <String>['--flavor', 'paid'],
    environment: environment,
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createIntegrationTestFlavorsTest({
  Map<String, String>? environment,
  String? deviceIdOverride,
}) {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/flavors',
    'integration_test/integration_test.dart',
    extraOptions: <String>['--flavor', 'paid'],
    environment: environment,
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createExternalTexturesFrameRateIntegrationTest({
  List<String> extraOptions = const <String>[],
}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/external_textures',
    'lib/frame_rate_main.dart',
    extraOptions: extraOptions,
  ).call;
}

TaskFunction createPlatformChannelSampleTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/examples/platform_channel',
    'test_driver/button_tap.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createPlatformChannelSwiftSampleTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/examples/platform_channel_swift',
    'test_driver/button_tap.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createHybridAndroidViewsIntegrationTest() {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/hybrid_android_views',
    'lib/main.dart',
  ).call;
}

TaskFunction createAndroidSemanticsIntegrationTest() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/android_semantics_testing',
    'integration_test/main_test.dart',
    withTalkBack: true,
  ).call;
}

TaskFunction createEndToEndKeyboardTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/keyboard_resize.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createEndToEndFrameNumberTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/frame_number.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createEndToEndDriverTest({
  Map<String, String>? environment,
  String? deviceIdOverride,
}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/driver.dart',
    environment: environment,
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createEndToEndKeyboardTextfieldTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/keyboard_textfield.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createSolidColorTest({required bool enableImpeller}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/solid_color.dart',
    extraOptions: <String>[if (enableImpeller) '--enable-impeller'],
  ).call;
}

TaskFunction createTextureTest({required bool enableImpeller}) {
  return DriverTest(
    '${flutterDirectory.path}/examples/texture',
    'test_driver/texture_test.dart',
    extraOptions: <String>[if (enableImpeller) '--enable-impeller'],
  ).call;
}

TaskFunction androidVerifiedInputTest({Map<String, String>? environment}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/android_verified_input',
    'lib/main.dart',
    environment: environment,
  ).call;
}

// Can run on emulator or physical android device.
// Device must have developer settings enabled.
// Device must be android api 30 or higher.
TaskFunction createDisplayCutoutTest() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/display_cutout_rotation/',
    'integration_test/display_cutout_test.dart',
    setup: (Device device) async {
      if (device is! AndroidDevice) {
        // Only android devices support this cutoutTest.
        throw TaskResult.failure('This test should only target android');
      }
      // Test requires developer settings added in 28 and behavior added in 30.
      final String sdkResult = await device.shellEval('getprop', <String>['ro.build.version.sdk']);
      if (sdkResult.startsWith('2') || sdkResult.startsWith('1') || sdkResult.length == 1) {
        throw TaskResult.failure('This test should only target android 30+.');
      }
      print('Adding Synthetic notch...');
      // This command will cause any running android activity to be recreated.
      await device.shellExec('cmd', <String>[
        'overlay',
        'enable',
        'com.android.internal.display.cutout.emulation.tall',
      ]);
    },
    tearDown: (Device device) async {
      if (device is AndroidDevice) {
        print('Removing Synthetic notch...');
        await device.shellExec('cmd', <String>[
          'overlay',
          'disable',
          'com.android.internal.display.cutout.emulation.tall',
        ]);
      }
    },
  ).call;
}

TaskFunction dartDefinesTask({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/defines.dart',
    deviceIdOverride: deviceIdOverride,
    extraOptions: <String>[
      '--dart-define=test.valueA=Example,A',
      '--dart-define=test.valueB=Value',
    ],
  ).call;
}

TaskFunction featureFlagsTask() {
  return () async {
    await flutter('config', options: const <String>['--enable-windowing']);

    return DriverTest(
      '${flutterDirectory.path}/dev/integration_tests/ui',
      'lib/feature_flags.dart',
    ).call();
  };
}

TaskFunction createEndToEndIntegrationTest({String? deviceIdOverride}) {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'integration_test/integration_test.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createSpellCheckIntegrationTest({String? deviceIdOverride}) {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/spell_check',
    'integration_test/integration_test.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createWindowsStartupDriverTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/windows_startup_test',
    'lib/main.dart',
    deviceIdOverride: deviceIdOverride,
  ).call;
}

TaskFunction createEngineIntegrationGoldenTest() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/engine_integration_golden_test',
    'integration_test/engine_integration_golden_test.dart',
    createPlatforms: <String>['windows'],
  ).call;
}

TaskFunction createWindowingDriverTest() {
  return () async {
    await flutter('config', options: const <String>['--enable-windowing']);
    return DriverTest(
      '${flutterDirectory.path}/dev/integration_tests/windowing_test',
      'lib/main.dart',
    ).call();
  };
}

TaskFunction createWideGamutTest() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/wide_gamut_test',
    'integration_test/app_test.dart',
    createPlatforms: <String>['ios', 'macos'],
  ).call;
}

class DriverTest {
  DriverTest(
    this.testDirectory,
    this.testTarget, {
    this.extraOptions = const <String>[],
    this.deviceIdOverride,
    this.environment,
  });

  final String testDirectory;
  final String testTarget;
  final List<String> extraOptions;
  final String? deviceIdOverride;
  final Map<String, String>? environment;

  Future<TaskResult> call() {
    return inDirectory<TaskResult>(testDirectory, () async {
      String deviceId;
      Device? selectedDevice;
      if (deviceIdOverride != null) {
        deviceId = deviceIdOverride!;
      } else {
        selectedDevice = await devices.workingDevice;
        await selectedDevice.unlock();
        deviceId = selectedDevice.deviceId;
      }
      await flutter('packages', options: <String>['get']);

      final bool isAndroidRun = selectedDevice != null
          ? selectedDevice is AndroidDevice
          : const <DeviceOperatingSystem>{
              DeviceOperatingSystem.android,
              DeviceOperatingSystem.androidArm,
              DeviceOperatingSystem.androidArm64,
            }.contains(deviceOperatingSystem);

      String? devicelabAdbPath;
      if (isAndroidRun) {
        try {
          devicelabAdbPath = adbPath;
        } on DeviceException {
          devicelabAdbPath = null;
        }
      }
      // Make the device ID available in the driver code, so tools like ADB can
      // reference it if needed.
      final env = <String, String>{
        ...?environment,
        'FLUTTER_DEVICE_ID_NUMBER': deviceId,
        'FLUTTER_ADB_PATH': ?devicelabAdbPath,
      };

      final options = <String>[
        '--no-android-gradle-daemon',
        '-v',
        '-t',
        testTarget,
        '-d',
        deviceId,
        ...extraOptions,
      ];
      await flutter('drive', options: options, environment: env);
      return TaskResult.success(null);
    });
  }
}

class IntegrationTest {
  IntegrationTest(
    this.testDirectory,
    this.testTarget, {
    this.extraOptions = const <String>[],
    this.createPlatforms = const <String>[],
    this.withTalkBack = false,
    this.environment,
    this.setup,
    this.tearDown,
    this.deviceIdOverride,
  });

  final String testDirectory;
  final String testTarget;
  final List<String> extraOptions;
  final List<String> createPlatforms;
  final bool withTalkBack;
  final Map<String, String>? environment;
  final String? deviceIdOverride;

  /// Run before flutter drive with the result from devices.workingDevice.
  final Future<void> Function(Device device)? setup;

  /// Run after flutter drive with the result from devices.workingDevice.
  final Future<void> Function(Device device)? tearDown;

  Future<TaskResult> call() {
    return inDirectory<TaskResult>(testDirectory, () async {
      String deviceId;
      Device? selectedDevice;
      if (deviceIdOverride != null) {
        deviceId = deviceIdOverride!;
      } else {
        selectedDevice = await devices.workingDevice;
        await selectedDevice.unlock();
        deviceId = selectedDevice.deviceId;
      }
      await flutter('packages', options: <String>['get']);
      await setup?.call(await devices.workingDevice);

      if (createPlatforms.isNotEmpty) {
        await flutter(
          'create',
          options: <String>['--platforms', createPlatforms.join(','), '--no-overwrite', '.'],
        );
      }

      if (withTalkBack) {
        if (selectedDevice is! AndroidDevice) {
          return TaskResult.failure(
            'A test that enables TalkBack can only be run on Android devices',
          );
        }
        await enableTalkBack();
      }

      final options = <String>['-v', '-d', deviceId, testTarget, ...extraOptions];
      await flutter('test', options: options, environment: environment);
      await tearDown?.call(await devices.workingDevice);

      if (withTalkBack) {
        await disableTalkBack();
      }

      return TaskResult.success(null);
    });
  }
}
