// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. 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:convert';
import 'dart:io';
import 'dart:math' as math;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:args/command_runner.dart';
import 'package:intl/intl.dart';
import 'package:path/path.dart' as path;

import 'perf/benchmarks_impl.dart';
import 'perf/flutter_analyze_benchmark.dart';

Future main(List<String> args) async {
  var benchmarks = <Benchmark>[
    ColdAnalysisBenchmark(ServerBenchmark.das),
    ColdAnalysisBenchmark(ServerBenchmark.lsp),
    AnalysisBenchmark(ServerBenchmark.das),
    AnalysisBenchmark(ServerBenchmark.lsp),
    FlutterAnalyzeBenchmark(),
  ];

  var runner =
      CommandRunner('benchmark', 'A benchmark runner for the analysis server.');
  runner.addCommand(ListCommand(benchmarks));
  runner.addCommand(RunCommand(benchmarks));
  runner.run(args);
}

String get analysisServerSrcPath {
  var script = Platform.script.toFilePath(windows: Platform.isWindows);
  var pkgPath = path.normalize(path.join(path.dirname(script), '..', '..'));
  return path.join(pkgPath, 'analysis_server');
}

void deleteServerCache() {
  // ~/.dartServer/.analysis-driver/
  ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
  var stateLocation = resourceProvider.getStateLocation('.analysis-driver');
  try {
    if (stateLocation != null && stateLocation.exists) {
      stateLocation.delete();
    }
  } catch (e) {
    // ignore any exception
  }
}

List<String> getProjectRoots({bool quick = false}) {
  var script = Platform.script.toFilePath(windows: Platform.isWindows);
  var pkgPath = path.normalize(path.join(path.dirname(script), '..', '..'));
  return <String>[path.join(pkgPath, quick ? 'meta' : 'analysis_server')];
}

abstract class Benchmark {
  final String id;
  final String description;
  final bool enabled;

  /// One of 'memory', 'cpu', or 'group'.
  final String kind;

  Benchmark(this.id, this.description,
      {this.enabled = true, this.kind = 'cpu'});

  int get maxIterations => 0;

  bool get needsSetup => false;

  Future oneTimeCleanup() => Future.value();

  Future oneTimeSetup() => Future.value();

  Future<BenchMarkResult> run({
    bool quick = false,
    bool verbose = false,
  });

  Map toJson() =>
      {'id': id, 'description': description, 'enabled': enabled, 'kind': kind};

  @override
  String toString() => '$id: $description';
}

class BenchMarkResult {
  static final NumberFormat nf = NumberFormat.decimalPattern();

  /// One of 'bytes', 'micros', or 'compound'.
  final String kindName;

  final int value;

  BenchMarkResult(this.kindName, this.value);

  BenchMarkResult combine(BenchMarkResult other) {
    return BenchMarkResult(kindName, math.min(value, other.value));
  }

  Map toJson() => {kindName: value};

  @override
  String toString() => '$kindName: ${nf.format(value)}';
}

class CompoundBenchMarkResult extends BenchMarkResult {
  final String name;

  Map<String, BenchMarkResult> results = {};

  CompoundBenchMarkResult(this.name) : super('compound', 0);

  void add(String name, BenchMarkResult result) {
    results[name] = result;
  }

  @override
  BenchMarkResult combine(BenchMarkResult other) {
    BenchMarkResult _combine(BenchMarkResult? a, BenchMarkResult? b) {
      if (a == null) return b!;
      if (b == null) return a;
      return a.combine(b);
    }

    var o = other as CompoundBenchMarkResult;

    var combined = CompoundBenchMarkResult(name);
    var keys = (<String>{}
          ..addAll(results.keys)
          ..addAll(o.results.keys))
        .toList();

    for (var key in keys) {
      combined.add(key, _combine(results[key], o.results[key]));
    }

    return combined;
  }

  @override
  Map toJson() {
    var m = <String, dynamic>{};
    for (var entry in results.entries) {
      m['$name-${entry.key}'] = entry.value.toJson();
    }
    return m;
  }

  @override
  String toString() => '${toJson()}';
}

class ListCommand extends Command {
  final List<Benchmark> benchmarks;

  ListCommand(this.benchmarks) {
    argParser.addFlag('machine',
        negatable: false, help: 'Emit the list of benchmarks as json.');
  }

  @override
  String get description => 'List available benchmarks.';

  @override
  String get invocation => '${runner!.executableName} $name';

  @override
  String get name => 'list';

  @override
  void run() {
    if (argResults!['machine'] as bool) {
      var map = <String, dynamic>{
        'benchmarks': benchmarks.map((b) => b.toJson()).toList()
      };
      print(JsonEncoder.withIndent('  ').convert(map));
    } else {
      for (var benchmark in benchmarks) {
        print('${benchmark.id}: ${benchmark.description}');
      }
    }
  }
}

class RunCommand extends Command {
  final List<Benchmark> benchmarks;

  RunCommand(this.benchmarks) {
    argParser.addFlag('quick',
        negatable: false,
        help: 'Run a quick version of the benchmark. This is not useful for '
            'gathering accurate times,\nbut can be used to validate that the '
            'benchmark works.');
    argParser.addOption('repeat',
        defaultsTo: '4', help: 'The number of times to repeat the benchmark.');
    argParser.addFlag('verbose',
        negatable: false,
        help: 'Print all communication to and from the analysis server.');
  }

  @override
  String get description => 'Run a given benchmark.';

  @override
  String get invocation => '${runner!.executableName} $name <benchmark-id>';

  @override
  String get name => 'run';

  @override
  Future run() async {
    if (argResults!.rest.isEmpty) {
      printUsage();
      exit(1);
    }

    var benchmarkId = argResults!.rest.first;
    var repeatCount = int.parse(argResults!['repeat'] as String);
    var quick = argResults!['quick'];
    var verbose = argResults!['verbose'];

    var benchmark =
        benchmarks.firstWhere((b) => b.id == benchmarkId, orElse: () {
      print("Benchmark '$benchmarkId' not found.");
      exit(1);
    });

    var actualIterations = repeatCount;
    if (benchmark.maxIterations > 0) {
      actualIterations = math.min(benchmark.maxIterations, repeatCount);
    }

    if (benchmark.needsSetup) {
      print('Setting up $benchmarkId...');
      await benchmark.oneTimeSetup();
    }

    try {
      BenchMarkResult? result;
      var time = Stopwatch()..start();
      print('Running $benchmarkId $actualIterations times...');

      for (var iteration = 0; iteration < actualIterations; iteration++) {
        var newResult = await benchmark.run(
          quick: quick,
          verbose: verbose,
        );
        print('  $newResult');
        result = result == null ? newResult : result.combine(newResult);
      }

      time.stop();
      print('Finished in ${time.elapsed.inSeconds} seconds.\n');
      var m = <String, dynamic>{
        'benchmark': benchmarkId,
        'result': result!.toJson()
      };
      print(json.encode(m));

      await benchmark.oneTimeCleanup();
    } catch (error, st) {
      print('$benchmarkId threw exception: $error');
      print(st);
      exit(1);
    }
  }
}
