// Copyright 2016 The Chromium 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 '../application_package.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/process.dart';
import '../cache.dart';
import '../dart/package_map.dart';
import '../dart/sdk.dart';
import '../device.dart';
import '../globals.dart';
import '../resident_runner.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import 'run.dart';

/// Runs integration (a.k.a. end-to-end) tests.
///
/// An integration test is a program that runs in a separate process from your
/// Flutter application. It connects to the application and acts like a user,
/// performing taps, scrolls, reading out widget properties and verifying their
/// correctness.
///
/// This command takes a target Flutter application that you would like to test
/// as the `--target` option (defaults to `lib/main.dart`). It then looks for a
/// corresponding test file within the `test_driver` directory. The test file is
/// expected to have the same name but contain the `_test.dart` suffix. The
/// `_test.dart` file would generally be a Dart program that uses
/// `package:flutter_driver` and exercises your application. Most commonly it
/// is a test written using `package:test`, but you are free to use something
/// else.
///
/// The app and the test are launched simultaneously. Once the test completes
/// the application is stopped and the command exits. If all these steps are
/// successful the exit code will be `0`. Otherwise, you will see a non-zero
/// exit code.
class DriveCommand extends RunCommandBase {
  DriveCommand() {
    requiresPubspecYaml();

    argParser
      ..addFlag('keep-app-running',
        defaultsTo: null,
        help: 'Will keep the Flutter application running when done testing.\n'
              'By default, "flutter drive" stops the application after tests are finished, '
              'and --keep-app-running overrides this. On the other hand, if --use-existing-app '
              'is specified, then "flutter drive" instead defaults to leaving the application '
              'running, and --no-keep-app-running overrides it.',
      )
      ..addOption('use-existing-app',
        help: 'Connect to an already running instance via the given observatory URL. '
              'If this option is given, the application will not be automatically started, '
              'and it will only be stopped if --no-keep-app-running is explicitly set.',
        valueHelp: 'url',
      )
      ..addOption('driver',
        help: 'The test file to run on the host (as opposed to the target file to run on '
              'the device).\n'
              'By default, this file has the same base name as the target file, but in the '
              '"test_driver/" directory instead, and with "_test" inserted just before the '
              'extension, so e.g. if the target is "lib/main.dart", the driver will be '
              '"test_driver/main_test.dart".',
        valueHelp: 'path',
      )
      ..addFlag('build',
        defaultsTo: true,
        help: 'Build the app before running.',
      );
  }

  @override
  final String name = 'drive';

  @override
  final String description = 'Runs Flutter Driver tests for the current project.';

  @override
  final List<String> aliases = <String>['driver'];

  Device _device;
  Device get device => _device;
  bool get shouldBuild => argResults['build'];

  /// Subscription to log messages printed on the device or simulator.
  // ignore: cancel_subscriptions
  StreamSubscription<String> _deviceLogSubscription;

  @override
  Future<FlutterCommandResult> runCommand() async {
    final String testFile = _getTestFile();
    if (testFile == null)
      throwToolExit(null);

    _device = await targetDeviceFinder();
    if (device == null)
      throwToolExit(null);

    if (await fs.type(testFile) != FileSystemEntityType.file)
      throwToolExit('Test file not found: $testFile');

    String observatoryUri;
    if (argResults['use-existing-app'] == null) {
      printStatus('Starting application: $targetFile');

      if (getBuildInfo().isRelease) {
        // This is because we need VM service to be able to drive the app.
        throwToolExit(
          'Flutter Driver does not support running in release mode.\n'
          '\n'
          'Use --profile mode for testing application performance.\n'
          'Use --debug (default) mode for testing correctness (with assertions).'
        );
      }

      final LaunchResult result = await appStarter(this);
      if (result == null)
        throwToolExit('Application failed to start. Will not run test. Quitting.', exitCode: 1);
      observatoryUri = result.observatoryUri.toString();
    } else {
      printStatus('Will connect to already running application instance.');
      observatoryUri = argResults['use-existing-app'];
    }

    Cache.releaseLockEarly();

    try {
      await testRunner(<String>[testFile], observatoryUri);
    } catch (error, stackTrace) {
      if (error is ToolExit)
        rethrow;
      throwToolExit('CAUGHT EXCEPTION: $error\n$stackTrace');
    } finally {
      if (argResults['keep-app-running'] ?? (argResults['use-existing-app'] != null)) {
        printStatus('Leaving the application running.');
      } else {
        printStatus('Stopping application instance.');
        await appStopper(this);
      }
    }

    return null;
  }

  String _getTestFile() {
    if (argResults['driver'] != null)
      return argResults['driver'];

    // If the --driver argument wasn't provided, then derive the value from
    // the target file.
    String appFile = fs.path.normalize(targetFile);

    // This command extends `flutter run` and therefore CWD == package dir
    final String packageDir = fs.currentDirectory.path;

    // Make appFile path relative to package directory because we are looking
    // for the corresponding test file relative to it.
    if (!fs.path.isRelative(appFile)) {
      if (!fs.path.isWithin(packageDir, appFile)) {
        printError(
          'Application file $appFile is outside the package directory $packageDir'
        );
        return null;
      }

      appFile = fs.path.relative(appFile, from: packageDir);
    }

    final List<String> parts = fs.path.split(appFile);

    if (parts.length < 2) {
      printError(
        'Application file $appFile must reside in one of the sub-directories '
        'of the package structure, not in the root directory.'
      );
      return null;
    }

    // Look for the test file inside `test_driver/` matching the sub-path, e.g.
    // if the application is `lib/foo/bar.dart`, the test file is expected to
    // be `test_driver/foo/bar_test.dart`.
    final String pathWithNoExtension = fs.path.withoutExtension(fs.path.joinAll(
      <String>[packageDir, 'test_driver']..addAll(parts.skip(1))));
    return '${pathWithNoExtension}_test${fs.path.extension(appFile)}';
  }
}

/// Finds a device to test on. May launch a simulator, if necessary.
typedef TargetDeviceFinder = Future<Device> Function();
TargetDeviceFinder targetDeviceFinder = findTargetDevice;
void restoreTargetDeviceFinder() {
  targetDeviceFinder = findTargetDevice;
}

Future<Device> findTargetDevice() async {
  final List<Device> devices = await deviceManager.getDevices().toList();

  if (deviceManager.hasSpecifiedDeviceId) {
    if (devices.isEmpty) {
      printStatus("No devices found with name or id matching '${deviceManager.specifiedDeviceId}'");
      return null;
    }
    if (devices.length > 1) {
      printStatus("Found ${devices.length} devices with name or id matching '${deviceManager.specifiedDeviceId}':");
      await Device.printDevices(devices);
      return null;
    }
    return devices.first;
  }

  if (devices.isEmpty) {
    printError('No devices found.');
    return null;
  } else if (devices.length > 1) {
    printStatus('Found multiple connected devices:');
    printStatus(devices.map<String>((Device d) => '  - ${d.name}\n').join(''));
  }
  printStatus('Using device ${devices.first.name}.');
  return devices.first;
}

/// Starts the application on the device given command configuration.
typedef AppStarter = Future<LaunchResult> Function(DriveCommand command);

AppStarter appStarter = _startApp; // (mutable for testing)
void restoreAppStarter() {
  appStarter = _startApp;
}

Future<LaunchResult> _startApp(DriveCommand command) async {
  final String mainPath = findMainDartFile(command.targetFile);
  if (await fs.type(mainPath) != FileSystemEntityType.file) {
    printError('Tried to run $mainPath, but that file does not exist.');
    return null;
  }

  printTrace('Stopping previously running application, if any.');
  await appStopper(command);

  final ApplicationPackage package = await command.applicationPackages
      .getPackageForPlatform(await command.device.targetPlatform);

  if (command.shouldBuild) {
    printTrace('Installing application package.');
    if (await command.device.isAppInstalled(package))
      await command.device.uninstallApp(package);
    await command.device.installApp(package);
  }

  final Map<String, dynamic> platformArgs = <String, dynamic>{};
  if (command.traceStartup)
    platformArgs['trace-startup'] = command.traceStartup;

  printTrace('Starting application.');

  // Forward device log messages to the terminal window running the "drive" command.
  command._deviceLogSubscription = command
      .device
      .getLogReader(app: package)
      .logLines
      .listen(printStatus);

  final LaunchResult result = await command.device.startApp(
    package,
    mainPath: mainPath,
    route: command.route,
    debuggingOptions: DebuggingOptions.enabled(
      command.getBuildInfo(),
      startPaused: true,
      observatoryPort: command.observatoryPort,
    ),
    platformArgs: platformArgs,
    prebuiltApplication: !command.shouldBuild,
    usesTerminalUi: false,
  );

  if (!result.started) {
    await command._deviceLogSubscription.cancel();
    return null;
  }

  return result;
}

/// Runs driver tests.
typedef TestRunner = Future<void> Function(List<String> testArgs, String observatoryUri);
TestRunner testRunner = _runTests;
void restoreTestRunner() {
  testRunner = _runTests;
}

Future<void> _runTests(List<String> testArgs, String observatoryUri) async {
  printTrace('Running driver tests.');

  PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(PackageMap.globalPackagesPath));
  final String dartVmPath = fs.path.join(dartSdkPath, 'bin', 'dart');
  final int result = await runCommandAndStreamOutput(
    <String>[dartVmPath]
      ..addAll(dartVmFlags)
      ..addAll(testArgs)
      ..addAll(<String>[
        '--packages=${PackageMap.globalPackagesPath}',
        '-rexpanded',
      ]),
    environment: <String, String>{'VM_SERVICE_URL': observatoryUri},
  );
  if (result != 0)
    throwToolExit('Driver tests failed: $result', exitCode: result);
}


/// Stops the application.
typedef AppStopper = Future<bool> Function(DriveCommand command);
AppStopper appStopper = _stopApp;
void restoreAppStopper() {
  appStopper = _stopApp;
}

Future<bool> _stopApp(DriveCommand command) async {
  printTrace('Stopping application.');
  final ApplicationPackage package = await command.applicationPackages.getPackageForPlatform(await command.device.targetPlatform);
  final bool stopped = await command.device.stopApp(package);
  await command._deviceLogSubscription?.cancel();
  return stopped;
}
