// 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:io';

import 'package:file/memory.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/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/terminal.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/globals.dart' as globals;
import 'package:flutter_tools/src/persistent_tool_state.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:unified_analytics/unified_analytics.dart';

import 'context.dart';
import 'fake_http_client.dart';
import 'fakes.dart';
import 'throwing_pub.dart';

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

// A default value should be provided if the vast majority of tests should use
// this provider. For example, [BufferLogger], [MemoryFileSystem].
final _testbedDefaults = <Type, Generator>{
  // Keeps tests fast by avoiding the actual file system.
  FileSystem: () => MemoryFileSystem(
    style: globals.platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
  ),
  ProcessManager: () => FakeProcessManager.any(),
  Logger: () => BufferLogger(
    terminal: AnsiTerminal(
      stdio: globals.stdio,
      platform: globals.platform,
    ), // Danger, using real stdio.
    outputPreferences: OutputPreferences.test(),
  ), // Allows reading logs and prevents stdout.
  OperatingSystemUtils: () => FakeOperatingSystemUtils(),
  OutputPreferences: () =>
      OutputPreferences.test(), // configures BufferLogger to avoid color codes.
  Analytics: () => const NoOpAnalytics(),
  FlutterVersion: () => FakeFlutterVersion(), // prevent requirement to mock git for test runner.
  Signals: () => FakeSignals(), // prevent registering actual signal handlers.
  Pub: () => const ThrowingPub(), // prevent accidental invocations of pub.
  BotDetector: () => const FakeBotDetector(true),
  Config: () => Config.test(
    name: Config.kFlutterSettings,
    directory: globals.fs.systemTempDirectory.createTempSync('flutter_config_dir_test.'),
    logger: globals.logger,
  ),
  PersistentToolState: () => PersistentToolState.test(
    directory: globals.fs.systemTempDirectory.createTempSync('flutter_config_dir_test.'),
    logger: globals.logger,
  ),
};

/// Manages interaction with the tool injection and runner system.
///
/// The Testbed automatically injects reasonable defaults through the context
/// DI system such as a [BufferLogger] and a [MemoryFileSystem].
///
/// Example:
///
/// Testing that a filesystem operation works as expected:
///
/// ```dart
/// void main() {
///   group('Example', () {
///     Testbed testbed;
///
///     setUp(() {
///       testbed = Testbed(setUp: () {
///         globals.fs.file('foo').createSync()
///       });
///     })
///
///     test('Can delete a file', () => testbed.run(() {
///       expect(globals.fs.file('foo').existsSync(), true);
///       globals.fs.file('foo').deleteSync();
///       expect(globals.fs.file('foo').existsSync(), false);
///     }));
///   });
/// }
/// ```
///
/// For a more detailed example, see the code in test_compiler_test.dart.
class TestBed {
  /// Creates a new [TestBed]
  ///
  /// `overrides` provides more overrides in addition to the test defaults.
  /// `setup` may be provided to apply mocks within the tool managed zone,
  /// including any specified overrides.
  TestBed({this._setup, this._overrides});

  final FutureOr<void> Function()? _setup;
  final Map<Type, Generator>? _overrides;

  /// Runs `test` within a tool zone.
  ///
  /// `overrides` may be used to provide new context values for the single test
  /// case or override any context values from the setup.
  Future<T?> run<T>(FutureOr<T> Function() test, {Map<Type, Generator>? overrides}) {
    final testOverrides = <Type, Generator>{
      ..._testbedDefaults,
      // Add the initial setUp overrides
      ...?_overrides,
      // Add the test-specific overrides
      ...?overrides,
    };
    if (testOverrides.containsKey(ProcessUtils)) {
      throw StateError('Do not inject ProcessUtils for testing, use ProcessManager instead.');
    }
    // Cache the original flutter root to restore after the test case.
    final String? originalFlutterRoot = Cache.flutterRoot;
    // Track pending timers to verify that they were correctly cleaned up.
    final timers = <Timer, StackTrace>{};

    return HttpOverrides.runZoned(() {
      return runInContext<T?>(() {
        return context.run<T?>(
          name: 'testbed-zone',
          zoneSpecification: ZoneSpecification(
            createTimer:
                (
                  Zone self,
                  ZoneDelegate parent,
                  Zone zone,
                  Duration duration,
                  void Function() timer,
                ) {
                  final Timer result = parent.createTimer(zone, duration, timer);
                  timers[result] = StackTrace.current;
                  return result;
                },
            createPeriodicTimer:
                (
                  Zone self,
                  ZoneDelegate parent,
                  Zone zone,
                  Duration period,
                  void Function(Timer) timer,
                ) {
                  final Timer result = parent.createPeriodicTimer(zone, period, timer);
                  timers[result] = StackTrace.current;
                  return result;
                },
          ),
          body: () async {
            Cache.flutterRoot = '';
            if (_setup != null) {
              await _setup.call();
            }
            await test();
            Cache.flutterRoot = originalFlutterRoot;
            for (final MapEntry<Timer, StackTrace> entry in timers.entries) {
              if (entry.key.isActive) {
                throw StateError('A Timer was active at the end of a test: ${entry.value}');
              }
            }
            return null;
          },
        );
      }, overrides: testOverrides);
    }, createHttpClient: (SecurityContext? c) => FakeHttpClient.any());
  }
}
