// 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() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/channels',
    'integration_test/main_test.dart',
  ).call;
}

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

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

TaskFunction createIntegrationTestFlavorsTest({Map<String, String>? environment}) {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/flavors',
    'integration_test/integration_test.dart',
    extraOptions: <String>['--flavor', 'paid'],
    environment: environment,
  ).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() {
  return DriverTest(
    '${flutterDirectory.path}/examples/platform_channel_swift',
    'test_driver/button_tap.dart',
  ).call;
}

TaskFunction createEmbeddedAndroidViewsIntegrationTest() {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/android_views',
    'lib/main.dart',
  ).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 createIOSPlatformViewTests() {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ios_platform_view_tests',
    'lib/main.dart',
    extraOptions: <String>['--dart-define=ENABLE_DRIVER_EXTENSION=true'],
  ).call;
}

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

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

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

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

TaskFunction createEndToEndKeyboardTextfieldTest() {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/keyboard_textfield.dart',
  ).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 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() {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'lib/defines.dart',
    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() {
  return IntegrationTest(
    '${flutterDirectory.path}/dev/integration_tests/ui',
    'integration_test/integration_test.dart',
  ).call;
}

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

TaskFunction createWindowsStartupDriverTest({String? deviceIdOverride}) {
  return DriverTest(
    '${flutterDirectory.path}/dev/integration_tests/windows_startup_test',
    'lib/main.dart',
    deviceIdOverride: deviceIdOverride,
  ).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'],
  ).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>{
        if (environment != null) ...environment!,
        'FLUTTER_DEVICE_ID_NUMBER': deviceId,
        if (devicelabAdbPath != null) '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,
  });

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

  /// 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 {
      final Device device = await devices.workingDevice;
      await device.unlock();
      final String deviceId = device.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 (device 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);
    });
  }
}
