// 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.

// @dart = 2.8

import 'dart:io';

import 'package:args/args.dart';

import '../framework/devices.dart';
import '../framework/task_result.dart';
import '../framework/utils.dart';

/// [Task] for defining build-test separation.
///
/// Using this [Task] allows DeviceLab capacity to only be spent on the [test].
abstract class BuildTestTask {
  BuildTestTask(this.args, {this.workingDirectory, this.runFlutterClean = true,}) {
    final ArgResults argResults = argParser.parse(args);
    applicationBinaryPath = argResults[kApplicationBinaryPathOption] as String;
    buildOnly = argResults[kBuildOnlyFlag] as bool;
    testOnly = argResults[kTestOnlyFlag] as bool;

  }

  static const String kApplicationBinaryPathOption = 'application-binary-path';
  static const String kBuildOnlyFlag = 'build';
  static const String kTestOnlyFlag = 'test';

  final ArgParser argParser = ArgParser()
    ..addOption(kApplicationBinaryPathOption)
    ..addFlag(kBuildOnlyFlag)
    ..addFlag(kTestOnlyFlag);

  /// Args passed from the test runner via "--task-arg".
  final List<String> args;

  /// If true, skip [test].
  bool buildOnly = false;

  /// If true, skip [build].
  bool testOnly = false;

  /// Whether to run `flutter clean` before building the application under test.
  final bool runFlutterClean;

  /// Path to a built application to use in [test].
  ///
  /// If not given, will default to child's expected location.
  String applicationBinaryPath;

  /// Where the test artifacts are stored, such as performance results.
  final Directory workingDirectory;

  /// Run Flutter build to create [applicationBinaryPath].
  Future<void> build() async {
    await inDirectory<void>(workingDirectory, () async {
      if (runFlutterClean) {
        section('FLUTTER CLEAN');
        await flutter('clean');
      }
      section('BUILDING APPLICATION');
      await flutter('build', options: getBuildArgs(deviceOperatingSystem));
    });

  }

  /// Run Flutter drive test from [getTestArgs] against the application under test on the device.
  ///
  /// This assumes that [applicationBinaryPath] exists.
  Future<TaskResult> test() async {
    final Device device = await devices.workingDevice;
    await device.unlock();
    await inDirectory<void>(workingDirectory, () async {
      section('DRIVE START');
      await flutter('drive', options: getTestArgs(deviceOperatingSystem, device.deviceId));
    });

    return parseTaskResult();
  }

  /// Args passed to flutter build to build the application under test.
  List<String> getBuildArgs(DeviceOperatingSystem deviceOperatingSystem) => throw UnimplementedError('getBuildArgs is not implemented');

  /// Args passed to flutter drive to test the built application.
  List<String> getTestArgs(DeviceOperatingSystem deviceOperatingSystem, String deviceId) => throw UnimplementedError('getTestArgs is not implemented');

  /// Logic to construct [TaskResult] from this test's results.
  Future<TaskResult> parseTaskResult() => throw UnimplementedError('parseTaskResult is not implemented');

  /// Path to the built application under test.
  ///
  /// Tasks can override to support default values. Otherwise, it will default
  /// to needing to be passed as an argument in the test runner.
  String getApplicationBinaryPath() => applicationBinaryPath;

  /// Run this task.
  ///
  /// Throws [Exception] when unnecessary arguments are passed.
  Future<TaskResult> call() async {
    if (buildOnly && testOnly) {
      throw Exception('Both build and test should not be passed. Pass only one.');
    }

    if (buildOnly && applicationBinaryPath != null) {
      throw Exception('Application binary path is only used for tests');
    }

    if (!testOnly) {
      await build();
    }

    if (buildOnly) {
      return TaskResult.buildOnly();
    }

    return test();
  }
}
