// 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 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_devtools_handler.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/run_hot.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:unified_analytics/unified_analytics.dart';
import 'package:vm_service/vm_service.dart' as vm_service;

import '../src/common.dart';
import '../src/context.dart';
import '../src/fakes.dart';
import 'hot_shared.dart';

void main() {
  group('validateReloadReport', () {
    testUsingContext('invalid', () async {
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{},
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[
          ],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <String, dynamic>{
            'message': 'error',
          },
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[
            <String, dynamic>{'message': false},
          ],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[
            <String, dynamic>{'message': <String>['error']},
          ],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[
            <String, dynamic>{'message': 'error'},
            <String, dynamic>{'message': <String>['error']},
          ],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': false,
        'details': <String, dynamic>{
          'notices': <Map<String, dynamic>>[
            <String, dynamic>{'message': 'error'},
          ],
        },
      })), false);
      expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
        'type': 'ReloadReport',
        'success': true,
      })), true);
    });

    testWithoutContext('ReasonForCancelling toString has a hint for specific errors', () {
      final ReasonForCancelling reasonForCancelling = ReasonForCancelling(
        message: 'Const class cannot remove fields',
      );

      expect(reasonForCancelling.toString(), contains('Try performing a hot restart instead.'));
    });
  });

  group('hotRestart', () {
    final FakeResidentCompiler residentCompiler = FakeResidentCompiler();
    late MemoryFileSystem fileSystem;
    late TestUsage testUsage;
    late FakeAnalytics fakeAnalytics;

    setUp(() {
      fileSystem = MemoryFileSystem.test();
      testUsage = TestUsage();
      fakeAnalytics = getInitializedFakeAnalyticsInstance(
        fs: fileSystem,
        fakeFlutterVersion: FakeFlutterVersion(),
      );
    });

    group('fails to setup', () {
      late TestHotRunnerConfig failingTestingConfig;
      setUp(() {
        failingTestingConfig = TestHotRunnerConfig(
          successfulHotRestartSetup: false,
          successfulHotReloadSetup: false,
        );
      });

      testUsingContext('setupHotRestart function fails', () async {
        fileSystem.file('.packages')
          ..createSync(recursive: true)
          ..writeAsStringSync('\n');
        final FakeDevice device = FakeDevice();
        final List<FlutterDevice> devices = <FlutterDevice>[
          FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler())
            ..devFS = FakeDevFs(),
        ];
        final OperationResult result = await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          analytics: fakeAnalytics,

        ).restart(fullRestart: true);
        expect(result.isOk, false);
        expect(result.message, 'setupHotRestart failed');
        expect(failingTestingConfig.updateDevFSCompleteCalled, false);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => failingTestingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('setupHotReload function fails', () async {
        fileSystem.file('.packages')
          ..createSync(recursive: true)
          ..writeAsStringSync('\n');
        final FakeDevice device = FakeDevice();
        final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
        final List<FlutterDevice> devices = <FlutterDevice>[
          fakeFlutterDevice,
        ];
        final OperationResult result = await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          reassembleHelper: (
            List<FlutterDevice?> flutterDevices,
            Map<FlutterDevice?, List<FlutterView>> viewCache,
            void Function(String message)? onSlow,
            String reloadMessage,
          ) async => ReassembleResult(
              <FlutterView?, FlutterVmService?>{null: null},
              false,
              true,
            ),
            analytics: fakeAnalytics,
        ).restart();
        expect(result.isOk, false);
        expect(result.message, 'setupHotReload failed');
        expect(failingTestingConfig.updateDevFSCompleteCalled, false);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => failingTestingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
      });
    });

    group('shutdown hook tests', () {
      late TestHotRunnerConfig shutdownTestingConfig;

      setUp(() {
        shutdownTestingConfig = TestHotRunnerConfig();
      });

      testUsingContext('shutdown hook called after signal', () async {
        fileSystem.file('.packages')
          ..createSync(recursive: true)
          ..writeAsStringSync('\n');
        final FakeDevice device = FakeDevice();
        final List<FlutterDevice> devices = <FlutterDevice>[
          FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()),
        ];
        await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          analytics: fakeAnalytics,
        ).cleanupAfterSignal();
        expect(shutdownTestingConfig.shutdownHookCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => shutdownTestingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('shutdown hook called after app stop', () async {
        fileSystem.file('.packages')
          ..createSync(recursive: true)
          ..writeAsStringSync('\n');
        final FakeDevice device = FakeDevice();
        final List<FlutterDevice> devices = <FlutterDevice>[
          FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()),
        ];
        await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          analytics: fakeAnalytics,
        ).preExit();
        expect(shutdownTestingConfig.shutdownHookCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => shutdownTestingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
      });
    });

    group('successful hot restart', () {
      late TestHotRunnerConfig testingConfig;
      setUp(() {
        testingConfig = TestHotRunnerConfig(
          successfulHotRestartSetup: true,
        );
      });
      testUsingContext('correctly tracks time spent for analytics for hot restart', () async {
        final FakeDevice device = FakeDevice();
        final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
        final List<FlutterDevice> devices = <FlutterDevice>[
          fakeFlutterDevice,
        ];

        fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
          success: true,
          invalidatedSourcesCount: 2,
          syncedBytes: 4,
          scannedSourcesCount: 8,
          compileDuration: const Duration(seconds: 16),
          transferDuration: const Duration(seconds: 32),
        );

        final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
          stopwatches: <String, Stopwatch>{
            'fullRestartHelper': FakeStopwatch()..elapsed = const Duration(seconds: 64),
            'updateDevFS': FakeStopwatch()..elapsed = const Duration(seconds: 128),
          },
        );

        (fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');

        final OperationResult result = await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          stopwatchFactory: fakeStopwatchFactory,
          analytics: fakeAnalytics,
        ).restart(fullRestart: true);

        expect(result.isOk, true);
        expect(testUsage.events, <TestUsageEvent>[
          const TestUsageEvent('hot', 'restart', parameters: CustomDimensions(
            hotEventTargetPlatform: 'flutter-tester',
            hotEventSdkName: 'Tester',
            hotEventEmulator: false,
            hotEventFullRestart: true,
            hotEventOverallTimeInMs: 64000,
            hotEventSyncedBytes: 4,
            hotEventInvalidatedSourcesCount: 2,
            hotEventTransferTimeInMs: 32000,
            hotEventCompileTimeInMs: 16000,
            hotEventFindInvalidatedTimeInMs: 128000,
            hotEventScannedSourcesCount: 8,
          )),
        ]);

        expect(fakeAnalytics.sentEvents, contains(
          Event.hotRunnerInfo(
            label: 'restart',
            targetPlatform: 'flutter-tester',
            sdkName: 'Tester',
            emulator: false,
            fullRestart: true,
            syncedBytes: 4,
            invalidatedSourcesCount: 2,
            transferTimeInMs: 32000,
            overallTimeInMs: 64000,
            compileTimeInMs: 16000,
            findInvalidatedTimeInMs: 128000,
            scannedSourcesCount: 8
          )
        ));
        expect(testingConfig.updateDevFSCompleteCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => testingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
        Usage: () => testUsage,
      });
    });

    group('successful hot reload', () {
      late TestHotRunnerConfig testingConfig;
      setUp(() {
        testingConfig = TestHotRunnerConfig(
          successfulHotReloadSetup: true,
        );
      });
      testUsingContext('correctly tracks time spent for analytics for hot reload', () async {
        final FakeDevice device = FakeDevice();
        final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
        final List<FlutterDevice> devices = <FlutterDevice>[
          fakeFlutterDevice,
        ];

        fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
          success: true,
          invalidatedSourcesCount: 6,
          syncedBytes: 8,
          scannedSourcesCount: 16,
          compileDuration: const Duration(seconds: 16),
          transferDuration: const Duration(seconds: 32),
        );

        final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
          stopwatches: <String, Stopwatch>{
            'updateDevFS': FakeStopwatch()..elapsed = const Duration(seconds: 64),
            'reloadSources:reload': FakeStopwatch()..elapsed = const Duration(seconds: 128),
            'reloadSources:reassemble': FakeStopwatch()..elapsed = const Duration(seconds: 256),
            'reloadSources:vm': FakeStopwatch()..elapsed = const Duration(seconds: 512),
          },
        );

        (fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');

        final OperationResult result = await HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          stopwatchFactory: fakeStopwatchFactory,
          analytics: fakeAnalytics,
          reloadSourcesHelper: (
            HotRunner hotRunner,
            List<FlutterDevice?> flutterDevices,
            bool? pause,
            Map<String, dynamic> firstReloadDetails,
            String? targetPlatform,
            String? sdkName,
            bool? emulator,
            String? reason,
            Usage usage,
            Analytics? analytics,
          ) async {
            firstReloadDetails['finalLibraryCount'] = 2;
            firstReloadDetails['receivedLibraryCount'] = 3;
            firstReloadDetails['receivedClassesCount'] = 4;
            firstReloadDetails['receivedProceduresCount'] = 5;
            return OperationResult.ok;
          },
          reassembleHelper: (
            List<FlutterDevice?> flutterDevices,
            Map<FlutterDevice?, List<FlutterView>> viewCache,
            void Function(String message)? onSlow,
            String reloadMessage,
          ) async => ReassembleResult(
              <FlutterView?, FlutterVmService?>{null: null},
              false,
              true,
            ),
        ).restart();

        expect(result.isOk, true);
        expect(testUsage.events, <TestUsageEvent>[
          const TestUsageEvent('hot', 'reload', parameters: CustomDimensions(
            hotEventFinalLibraryCount: 2,
            hotEventSyncedLibraryCount: 3,
            hotEventSyncedClassesCount: 4,
            hotEventSyncedProceduresCount: 5,
            hotEventSyncedBytes: 8,
            hotEventInvalidatedSourcesCount: 6,
            hotEventTransferTimeInMs: 32000,
            hotEventOverallTimeInMs: 128000,
            hotEventTargetPlatform: 'flutter-tester',
            hotEventSdkName: 'Tester',
            hotEventEmulator: false,
            hotEventFullRestart: false,
            hotEventCompileTimeInMs: 16000,
            hotEventFindInvalidatedTimeInMs: 64000,
            hotEventScannedSourcesCount: 16,
            hotEventReassembleTimeInMs: 256000,
            hotEventReloadVMTimeInMs: 512000,
          )),
        ]);
        expect(fakeAnalytics.sentEvents, contains(
          Event.hotRunnerInfo(
            label: 'reload',
            targetPlatform: 'flutter-tester',
            sdkName: 'Tester',
            emulator: false,
            fullRestart: false,
            finalLibraryCount: 2,
            syncedLibraryCount: 3,
            syncedClassesCount: 4,
            syncedProceduresCount: 5,
            syncedBytes: 8,
            invalidatedSourcesCount: 6,
            transferTimeInMs: 32000,
            overallTimeInMs: 128000,
            compileTimeInMs: 16000,
            findInvalidatedTimeInMs: 64000,
            scannedSourcesCount: 16,
            reassembleTimeInMs: 256000,
            reloadVMTimeInMs: 512000
          ),
        ));
        expect(testingConfig.updateDevFSCompleteCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => testingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
        Usage: () => testUsage,
      });
    });

    group('hot restart that failed to sync dev fs', () {
      late TestHotRunnerConfig testingConfig;
      setUp(() {
        testingConfig = TestHotRunnerConfig(
          successfulHotRestartSetup: true,
        );
      });
      testUsingContext('still calls the devfs complete callback', () async {
        final FakeDevice device = FakeDevice();
        final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
        final List<FlutterDevice> devices = <FlutterDevice>[
          fakeFlutterDevice,
        ];
        fakeFlutterDevice.updateDevFSReportCallback = () async => throw Exception('updateDevFS failed');

        final HotRunner runner = HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          analytics: fakeAnalytics,
        );

        await expectLater(runner.restart(fullRestart: true), throwsA(isA<Exception>().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed')));
        expect(testingConfig.updateDevFSCompleteCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => testingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
        Usage: () => testUsage,
      });
    });

    group('hot reload that failed to sync dev fs', () {
      late TestHotRunnerConfig testingConfig;
      setUp(() {
        testingConfig = TestHotRunnerConfig(
          successfulHotReloadSetup: true,
        );
      });
      testUsingContext('still calls the devfs complete callback', () async {
        final FakeDevice device = FakeDevice();
        final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
        final List<FlutterDevice> devices = <FlutterDevice>[
          fakeFlutterDevice,
        ];
        fakeFlutterDevice.updateDevFSReportCallback = () async => throw Exception('updateDevFS failed');

        final HotRunner runner = HotRunner(
          devices,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
          target: 'main.dart',
          devtoolsHandler: createNoOpHandler,
          analytics: fakeAnalytics,
        );

        await expectLater(runner.restart(), throwsA(isA<Exception>().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed')));
        expect(testingConfig.updateDevFSCompleteCalled, true);
      }, overrides: <Type, Generator>{
        HotRunnerConfig: () => testingConfig,
        Artifacts: () => Artifacts.test(),
        FileSystem: () => fileSystem,
        Platform: () => FakePlatform(),
        ProcessManager: () => FakeProcessManager.any(),
        Usage: () => testUsage,
      });
    });
  });

  group('hot attach', () {
    late MemoryFileSystem fileSystem;
    late FakeAnalytics fakeAnalytics;

    setUp(() {
      fileSystem = MemoryFileSystem.test();
      fakeAnalytics = getInitializedFakeAnalyticsInstance(
        fs: fileSystem,
        fakeFlutterVersion: FakeFlutterVersion(),
      );
    });

    testUsingContext('Exits with code 2 when HttpException is thrown '
      'during VM service connection', () async {
      fileSystem.file('.packages')
        ..createSync(recursive: true)
        ..writeAsStringSync('\n');

      final FakeResidentCompiler residentCompiler = FakeResidentCompiler();
      final FakeDevice device = FakeDevice();
      final List<FlutterDevice> devices = <FlutterDevice>[
        TestFlutterDevice(
          device: device,
          generator: residentCompiler,
          exception: const HttpException('Connection closed before full header was received, '
              'uri = http://127.0.0.1:63394/5ZmLv8A59xY=/ws'),
        ),
      ];

      final int exitCode = await HotRunner(devices,
        debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
        target: 'main.dart',
        analytics: fakeAnalytics,
      ).attach(needsFullRestart: false);
      expect(exitCode, 2);
    }, overrides: <Type, Generator>{
      HotRunnerConfig: () => TestHotRunnerConfig(),
      Artifacts: () => Artifacts.test(),
      FileSystem: () => fileSystem,
      Platform: () => FakePlatform(),
      ProcessManager: () => FakeProcessManager.any(),
    });
  });

  group('hot cleanupAtFinish()', () {
    late MemoryFileSystem fileSystem;
    late FakeAnalytics fakeAnalytics;

    setUp(() {
      fileSystem = MemoryFileSystem.test();
      fakeAnalytics = getInitializedFakeAnalyticsInstance(
        fs: fileSystem,
        fakeFlutterVersion: FakeFlutterVersion(),
      );
    });

    testUsingContext('disposes each device', () async {
      final FakeDevice device1 = FakeDevice();
      final FakeDevice device2 = FakeDevice();
      final FakeFlutterDevice flutterDevice1 = FakeFlutterDevice(device1);
      final FakeFlutterDevice flutterDevice2 = FakeFlutterDevice(device2);

      final List<FlutterDevice> devices = <FlutterDevice>[
        flutterDevice1,
        flutterDevice2,
      ];

      await HotRunner(devices,
        debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
        target: 'main.dart',
        analytics: fakeAnalytics,
      ).cleanupAtFinish();

      expect(device1.disposed, true);
      expect(device2.disposed, true);

      expect(flutterDevice1.stoppedEchoingDeviceLog, true);
      expect(flutterDevice2.stoppedEchoingDeviceLog, true);
    });
  });
}
