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

import 'package:path/path.dart' as path;

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

/// Run each benchmark this many times and compute average, min, max.
const int _kRunsPerBenchmark = 10;

Future<TaskResult> flutterToolStartupBenchmarkTask() async {
  final Directory projectParentDirectory =
      Directory.systemTemp.createTempSync('flutter_tool_startup_benchmark');
  final Directory projectDirectory =
      dir(path.join(projectParentDirectory.path, 'benchmark'));
  await inDirectory<void>(flutterDirectory, () async {
    await flutter('update-packages');
    await flutter('create', options: <String>[projectDirectory.path]);
    // Remove 'test' directory so we don't time the actual testing, but only the launching of the flutter tool
    rmTree(dir(path.join(projectDirectory.path, 'test')));
  });

  final Map<String, dynamic> data = <String, dynamic>{
    // `flutter test` in dir with no `test` folder.
    ...(await _Benchmark(
      projectDirectory,
      'test startup',
      'test',
    ).run())
        .asMap('flutter_tool_startup_test'),

    // `flutter test -d foo_device` in dir woth no `test` folder.
    ...(await _Benchmark(
      projectDirectory,
      'test startup with specified device',
      'test',
      options: <String>['-d', 'foo_device'],
    ).run())
        .asMap('flutter_tool_startup_test_with_specified_device'),

    // `flutter test -v` where no android sdk will be found (at least currently).
    ...(await _Benchmark(
      projectDirectory,
      'test startup no android sdk',
      'test',
      options: <String>['-v'],
      environment: <String, String>{
        'ANDROID_HOME': 'dummy value',
        'ANDROID_SDK_ROOT': 'dummy value',
        'PATH': pathWithoutWhereHits(<String>['adb', 'aapt']),
      },
    ).run())
        .asMap('flutter_tool_startup_test_no_android_sdk'),

    // `flutter -h`.
    ...(await _Benchmark(
      projectDirectory,
      'help startup',
      '-h',
    ).run())
        .asMap('flutter_tool_startup_help'),
  };

  // Cleanup.
  rmTree(projectParentDirectory);

  return TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
}

String pathWithoutWhereHits(List<String> whats) {
  final String pathEnvironment = Platform.environment['PATH'] ?? '';
  List<String> paths;
  if (Platform.isWindows) {
    paths = pathEnvironment.split(';');
  } else {
    paths = pathEnvironment.split(':');
  }
  // This isn't great but will probably work for our purposes.
  final List<String> extensions = <String>['', '.exe', '.bat', '.com'];

  final List<String> notFound = <String>[];
  for (final String path in paths) {
    bool found = false;
    for (final String extension in extensions) {
      for (final String what in whats) {
        final File f = File('$path${Platform.pathSeparator}$what$extension');
        if (f.existsSync()) {
          found = true;
          break;
        }
      }
      if (found) {
        break;
      }
    }
    if (!found) {
      notFound.add(path);
    }
  }

  if (Platform.isWindows) {
    return notFound.join(';');
  } else {
    return notFound.join(':');
  }
}

class _BenchmarkResult {
  const _BenchmarkResult(this.mean, this.min, this.max);

  final int mean; // Milliseconds

  final int min; // Milliseconds

  final int max; // Milliseconds

  Map<String, dynamic> asMap(String name) {
    return <String, dynamic>{
      name: mean,
      '${name}_minimum': min,
      '${name}_maximum': max,
    };
  }
}

class _Benchmark {
  _Benchmark(this.directory, this.title, this.command,
      {this.options = const <String>[], this.environment});

  final Directory directory;

  final String title;

  final String command;

  final List<String> options;

  final Map<String, String>? environment;

  Future<int> execute(int iteration, int targetIterations) async {
    section('Benchmark $title - ${iteration + 1} / $targetIterations');
    final Stopwatch stopwatch = Stopwatch();
    await inDirectory<void>(directory, () async {
      stopwatch.start();
      // canFail is set to true, as e.g. `flutter test` in a dir with no `test`
      // directory sets a non-zero return value.
      await flutter(command,
          options: options, canFail: true, environment: environment);
      stopwatch.stop();
    });
    return stopwatch.elapsedMilliseconds;
  }

  /// Runs `benchmark` several times and reports the results.
  Future<_BenchmarkResult> run() async {
    final List<int> results = <int>[];
    int sum = 0;
    for (int i = 0; i < _kRunsPerBenchmark; i++) {
      final int thisRuntime = await execute(i, _kRunsPerBenchmark);
      results.add(thisRuntime);
      sum += thisRuntime;
    }
    results.sort();
    return _BenchmarkResult(sum ~/ results.length, results.first, results.last);
  }
}
