// 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 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/bot_detector.dart';
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/template.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/build_system/build_targets.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/context_runner.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/ios/simulators.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/isolated/build_targets.dart';
import 'package:flutter_tools/src/isolated/mustache_template.dart';
import 'package:flutter_tools/src/persistent_tool_state.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/crash_reporting.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:meta/meta.dart';
import 'package:test/fake.dart';
import 'package:unified_analytics/unified_analytics.dart';

import 'common.dart';
import 'fake_http_client.dart';
import 'fake_process_manager.dart';
import 'fakes.dart';
import 'throwing_pub.dart';

export 'package:flutter_tools/src/base/context.dart' show Generator;

export 'fake_process_manager.dart' show FakeCommand, FakeProcessManager, ProcessManager;

/// Return the test logger. This assumes that the current Logger is a BufferLogger.
BufferLogger get testLogger => context.get<Logger>()! as BufferLogger;

FakeDeviceManager get testDeviceManager => context.get<DeviceManager>()! as FakeDeviceManager;

@isTest
void testUsingContext(
  String description,
  dynamic Function() testMethod, {
  Map<Type, Generator> overrides = const <Type, Generator>{},
  bool initializeFlutterRoot = true,
  String? testOn,
  bool? skip, // should default to `false`, but https://github.com/dart-lang/test/issues/545 doesn't allow this
}) {
  if (overrides[FileSystem] != null && overrides[ProcessManager] == null) {
    fail(
      'If you override the FileSystem context you must also provide a ProcessManager, '
      'otherwise the processes you launch will not be dealing with the same file system '
      'that you are dealing with in your test.',
    );
  }
  if (overrides.containsKey(ProcessUtils)) {
    fail('Do not inject ProcessUtils for testing, use ProcessManager instead.');
  }

  // Ensure we don't rely on the default [Config] constructor which will
  // leak a sticky $HOME/.flutter_settings behind!
  Directory? configDir;
  tearDown(() {
    if (configDir != null) {
      tryToDelete(configDir!);
      configDir = null;
    }
  });
  Config buildConfig(FileSystem fs) {
    configDir ??= globals.fs.systemTempDirectory.createTempSync('flutter_config_dir_test.');
    return Config.test(name: Config.kFlutterSettings, directory: configDir, logger: globals.logger);
  }

  PersistentToolState buildPersistentToolState(FileSystem fs) {
    configDir ??= globals.fs.systemTempDirectory.createTempSync('flutter_config_dir_test.');
    return PersistentToolState.test(directory: configDir!, logger: globals.logger);
  }

  test(
    description,
    () async {
      await runInContext<dynamic>(
        () {
          return context.run<dynamic>(
            name: 'mocks',
            overrides: <Type, Generator>{
              AnsiTerminal: () => AnsiTerminal(platform: globals.platform, stdio: globals.stdio),
              Config: () => buildConfig(globals.fs),
              DeviceManager: () => FakeDeviceManager(),
              Doctor: () => _ContextFakeDoctor(globals.logger),
              FlutterVersion: () => FakeFlutterVersion(),
              HttpClient: () => FakeHttpClient.any(),
              IOSSimulatorUtils: () => const NoopIOSSimulatorUtils(),
              OutputPreferences: () => OutputPreferences.test(),
              Logger: () => BufferLogger.test(outputPreferences: context.get<OutputPreferences>()),
              OperatingSystemUtils: () => FakeOperatingSystemUtils(),
              PersistentToolState: () => buildPersistentToolState(globals.fs),
              XcodeProjectInterpreter: () => FakeXcodeProjectInterpreter(),
              FileSystem: () => LocalFileSystemBlockingSetCurrentDirectory(),
              PlistParser: () => FakePlistParser(),
              Signals: () => FakeSignals(),
              Pub: () => const ThrowingPub(), // prevent accidentally using pub.
              CrashReporter: () => const NoopCrashReporter(),
              TemplateRenderer: () => const MustacheTemplateRenderer(),
              BuildTargets: () => const BuildTargetsImpl(),
              Analytics: () => const NoOpAnalytics(),
              Stdio: () => FakeStdio(),
            },
            body: () {
              // To catch all errors thrown by the test, even uncaught async errors, we use a zone.
              //
              // Zones introduce their own event loop, so we do not await futures created inside
              // the zone from outside the zone. Instead, we create a Completer outside the zone,
              // and have the test complete it when the test ends (in success or failure), and we
              // await that.
              final completer = Completer<void>();
              runZonedGuarded<Future<dynamic>>(
                () async {
                  try {
                    return await context.run<dynamic>(
                      // Apply the overrides to the test context in the zone since their
                      // instantiation may reference items already stored on the context.
                      overrides: overrides,
                      name: 'test-specific overrides',
                      body: () async {
                        if (initializeFlutterRoot) {
                          // Provide a sane default for the flutterRoot directory. Individual
                          // tests can override this either in the test or during setup.
                          Cache.flutterRoot ??= getFlutterRoot();
                        }
                        return await testMethod();
                      },
                    );
                  } finally {
                    // We do not need a catch { ... } block because the error zone
                    // will catch all errors and send them to the completer below.
                    //
                    // See https://github.com/flutter/flutter/pull/141821/files#r1462288131.
                    if (!completer.isCompleted) {
                      completer.complete();
                    }
                  }
                },
                (Object error, StackTrace stackTrace) {
                  // When things fail, it's ok to print to the console!
                  print(error); // ignore: avoid_print
                  print(stackTrace); // ignore: avoid_print
                  _printBufferedErrors(context);
                  if (!completer.isCompleted) {
                    completer.completeError(error, stackTrace);
                  }
                  throw error; //ignore: only_throw_errors
                },
              );
              return completer.future;
            },
          );
        },
        overrides: <Type, Generator>{
          // This has to go here so that runInContext will pick it up when it tries
          // to do bot detection before running the closure. This is important
          // because the test may be giving us a fake HttpClientFactory, which may
          // throw in unexpected/abnormal ways.
          // If a test needs a BotDetector that does not always return true, it
          // can provide the AlwaysFalseBotDetector in the overrides, or its own
          // BotDetector implementation in the overrides.
          BotDetector: overrides[BotDetector] ?? () => const FakeBotDetector(true),
        },
      );
    },
    testOn: testOn,
    skip: skip,
  );
  // We don't support "timeout"; see ../../dart_test.yaml which
  // configures all tests to have a 15 minute timeout which should
  // definitely be enough.
}

void _printBufferedErrors(AppContext testContext) {
  if (testContext.get<Logger>() is BufferLogger) {
    final bufferLogger = testContext.get<Logger>()! as BufferLogger;
    if (bufferLogger.errorText.isNotEmpty) {
      // This is where the logger outputting errors is implemented, so it has
      // to use `print`.
      print(bufferLogger.errorText); // ignore: avoid_print
    }
    bufferLogger.clear();
  }
}

class FakeDeviceManager implements DeviceManager {
  List<Device> attachedDevices = <Device>[];
  List<Device> wirelessDevices = <Device>[];

  String? _specifiedDeviceId;

  @override
  String? get specifiedDeviceId {
    if (_specifiedDeviceId == null || _specifiedDeviceId == 'all') {
      return null;
    }
    return _specifiedDeviceId;
  }

  @override
  void stopExtendedWirelessDeviceDiscoverers() {}

  @override
  set specifiedDeviceId(String? id) {
    _specifiedDeviceId = id;
  }

  @override
  bool get hasSpecifiedDeviceId => specifiedDeviceId != null;

  @override
  bool get hasSpecifiedAllDevices {
    return _specifiedDeviceId != null && _specifiedDeviceId == 'all';
  }

  @override
  Future<List<Device>> getAllDevices({DeviceDiscoveryFilter? filter}) async =>
      filteredDevices(filter);

  @override
  Future<List<Device>> refreshAllDevices({
    Duration? timeout,
    DeviceDiscoveryFilter? filter,
  }) async => filteredDevices(filter);

  @override
  Future<List<Device>> refreshExtendedWirelessDeviceDiscoverers({
    Duration? timeout,
    DeviceDiscoveryFilter? filter,
  }) async => filteredDevices(filter);

  @override
  Future<List<Device>> getDevicesById(
    String deviceId, {
    DeviceDiscoveryFilter? filter,
    bool waitForDeviceToConnect = false,
  }) async {
    return filteredDevices(filter).where((Device device) {
      return device.id == deviceId || device.id.startsWith(deviceId);
    }).toList();
  }

  @override
  Future<List<Device>> getDevices({
    DeviceDiscoveryFilter? filter,
    bool waitForDeviceToConnect = false,
  }) {
    return hasSpecifiedDeviceId
        ? getDevicesById(specifiedDeviceId!, filter: filter)
        : getAllDevices(filter: filter);
  }

  void addAttachedDevice(Device device) => attachedDevices.add(device);
  void addWirelessDevice(Device device) => wirelessDevices.add(device);

  @override
  bool get canListAnything => true;

  @override
  Future<List<String>> getDeviceDiagnostics() async => <String>[];

  @override
  List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];

  @override
  DeviceDiscoverySupportFilter deviceSupportFilter({
    bool includeDevicesUnsupportedByProject = false,
    FlutterProject? flutterProject,
  }) {
    return TestDeviceDiscoverySupportFilter();
  }

  @override
  Device? getSingleEphemeralDevice(List<Device> devices) => null;

  List<Device> filteredDevices(DeviceDiscoveryFilter? filter) {
    return switch (filter?.deviceConnectionInterface) {
      DeviceConnectionInterface.attached => attachedDevices,
      DeviceConnectionInterface.wireless => wirelessDevices,
      null => attachedDevices + wirelessDevices,
    };
  }
}

class TestDeviceDiscoverySupportFilter extends Fake implements DeviceDiscoverySupportFilter {
  TestDeviceDiscoverySupportFilter();
}

class FakeAndroidLicenseValidator extends Fake implements AndroidLicenseValidator {
  @override
  Future<LicensesAccepted> get licensesAccepted async => LicensesAccepted.all;
}

class _ContextFakeDoctor extends Doctor {
  _ContextFakeDoctor(Logger logger, {super.clock = const SystemClock()}) : super(logger: logger);

  // True for testing.
  @override
  bool get canListAnything => true;

  // True for testing.
  @override
  bool get canLaunchAnything => true;

  @override
  /// Replaces the android workflow with a version that overrides licensesAccepted,
  /// to prevent individual tests from having to mock out the process for
  /// the Doctor.
  List<DoctorValidator> get validators {
    final List<DoctorValidator> superValidators = super.validators;
    return superValidators.map<DoctorValidator>((DoctorValidator v) {
      if (v is AndroidLicenseValidator) {
        return FakeAndroidLicenseValidator();
      }
      return v;
    }).toList();
  }
}

class NoopIOSSimulatorUtils implements IOSSimulatorUtils {
  const NoopIOSSimulatorUtils();

  @override
  Future<List<IOSSimulator>> getAttachedDevices() async => <IOSSimulator>[];

  @override
  Future<List<IOSSimulatorRuntime>> getAvailableIOSRuntimes() async => <IOSSimulatorRuntime>[];
}

class FakeXcodeProjectInterpreter implements XcodeProjectInterpreter {
  FakeXcodeProjectInterpreter({
    this._isInstalled = true,
    this._versionText = 'Xcode 15',
    this._version = const Version.withText(15, 0, 0, '15.0.0'),
    this._build = '15A240D',
  });

  final bool _isInstalled;
  final String? _versionText;
  final Version? _version;
  final String? _build;

  @override
  bool get isInstalled => _isInstalled;

  @override
  String? get versionText => _versionText;

  @override
  Version? get version => _version;

  @override
  String? get build => _build;

  @override
  Future<Map<String, String>> getBuildSettings(
    XcodeBasedProject xcodeProject, {
    required XcodeProjectBuildContext buildContext,
    Duration timeout = const Duration(minutes: 1),
  }) async {
    return <String, String>{};
  }

  @override
  Future<String> pluginsBuildSettingsOutput(
    Directory podXcodeProject, {
    Duration timeout = const Duration(minutes: 1),
  }) async {
    return '';
  }

  @override
  Future<void> cleanWorkspace(
    XcodeBasedProject xcodeProject,
    String workspacePath,
    String scheme, {
    required Directory buildDirectory,
    bool verbose = false,
  }) async {}

  @override
  Future<XcodeProjectInfo?> getInfo(
    XcodeBasedProject xcodeProject, {
    String? projectFilename,
    required Directory buildDirectory,
  }) async {
    return XcodeProjectInfo(<String>['Runner'], <String>['Debug', 'Release'], <String>[
      'Runner',
    ], BufferLogger.test());
  }

  @override
  List<String> xcrunCommand() => <String>['xcrun'];

  @override
  Future<void> prefetchSwiftPackagesForProject(
    XcodeBasedProject xcodeProject, {
    required Directory buildDirectory,
  }) async {}

  @override
  Future<List<String>> fetchDependenciesAndGenerateXcodebuildArgs(
    XcodeBasedProject xcodeProject,
    Directory buildDirectory, {
    bool skipPackageValidation = true,
  }) async {
    return <String>['xcrun', 'xcodebuild'];
  }

  @override
  String swiftPackageCachePath(Directory buildDirectory) {
    return '';
  }
}

/// Prevent test crashes from being reported to the crash backend.
class NoopCrashReporter implements CrashReporter {
  const NoopCrashReporter();

  @override
  Future<void> informUser(CrashDetails details, File crashFile) async {}
}

class LocalFileSystemBlockingSetCurrentDirectory extends LocalFileSystem {
  // Use [FakeSignals] so developers running the test suite can kill the test
  // runner.
  LocalFileSystemBlockingSetCurrentDirectory() : super.test(signals: FakeSignals());

  @override
  set currentDirectory(dynamic value) {
    throw Exception(
      'globals.fs.currentDirectory should not be set on the local file system during '
      'tests as this can cause race conditions with concurrent tests. '
      'Consider using a MemoryFileSystem for testing if possible or refactor '
      'code to not require setting globals.fs.currentDirectory.',
    );
  }
}

class FakeSignals implements Signals {
  @override
  Object addHandler(ProcessSignal signal, SignalHandler handler) {
    return const Object();
  }

  @override
  Future<bool> removeHandler(ProcessSignal signal, Object token) async {
    return true;
  }

  @override
  Stream<Object> get errors => const Stream<Object>.empty();
}
