// Copyright (c) 2016, 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.

/// An entrypoint used to run portions of analyzer and measure its performance.
import 'dart:io' show exit;

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart'
    show Folder, ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart'
    show PhysicalResourceProvider;
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';

void main(List<String> args) async {
  // TODO(sigmund): provide sdk folder as well.
  if (args.length < 2) {
    print('usage: perf.dart <bench-id> <entry.dart>');
    exit(1);
  }
  var totalTimer = Stopwatch()..start();

  var bench = args[0];
  var entryUri = Uri.base.resolve(args[1]);

  await setup(args[1]);

  if (bench == 'scan') {
    var files = scanReachableFiles(entryUri);
    // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
    for (var i = 0; i < 10; i++) {
      scanFiles(files);
    }
  } else if (bench == 'parse') {
    var files = scanReachableFiles(entryUri);
    // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
    for (var i = 0; i < 10; i++) {
      parseFiles(files);
    }
  } else {
    print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
    // TODO(sigmund): implement the remaining benchmarks.
    exit(1);
  }

  totalTimer.stop();
  report('total', totalTimer.elapsedMicroseconds);
}

/// Cumulative time spent scanning.
Stopwatch scanTimer = Stopwatch();

/// Cumulative total number of chars scanned.
int scanTotalChars = 0;

/// Factory to load and resolve app, packages, and sdk sources.
late SourceFactory sources;

/// Add to [files] all sources reachable from [start].
void collectSources(Source? start, Set<Source?> files) {
  if (!files.add(start)) return;
  var unit = parseDirectives(start!);
  for (var directive in unit.directives) {
    if (directive is UriBasedDirective) {
      var next = sources.resolveUri(start, directive.uri.stringValue);
      collectSources(next, files);
    }
  }
}

/// Uses the diet-parser to parse only directives in [source].
CompilationUnit parseDirectives(Source source) {
  var token = tokenize(source);
  var parser = Parser(
    source,
    AnalysisErrorListener.NULL_LISTENER,
    featureSet: FeatureSet.latestLanguageVersion(),
  );
  return parser.parseDirectives(token);
}

/// Parses every file in [files] and reports the time spent doing so.
void parseFiles(Set<Source?> files) {
  // The code below will record again how many chars are scanned and how long it
  // takes to scan them, even though we already did so in [scanReachableFiles].
  // Recording and reporting this twice is unnecessary, but we do so for now to
  // validate that the results are consistent.
  scanTimer = Stopwatch();
  var old = scanTotalChars;
  scanTotalChars = 0;
  var parseTimer = Stopwatch()..start();
  for (var source in files) {
    parseFull(source!);
  }
  parseTimer.stop();

  // Report size and scanning time again. See discussion above.
  if (old != scanTotalChars) print('input size changed? $old chars');
  report('scan', scanTimer.elapsedMicroseconds);

  var pTime = parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
  report('parse', pTime);
}

/// Parse the full body of [source] and return it's compilation unit.
CompilationUnit parseFull(Source source) {
  var token = tokenize(source);
  var parser = Parser(
    source,
    AnalysisErrorListener.NULL_LISTENER,
    featureSet: FeatureSet.latestLanguageVersion(),
  );
  return parser.parseCompilationUnit(token);
}

/// Report that metric [name] took [time] micro-seconds to process
/// [scanTotalChars] characters.
void report(String name, int time) {
  var sb = StringBuffer();
  sb.write('$name: $time us, ${time ~/ 1000} ms');
  sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
  print('$sb');
}

/// Scans every file in [files] and reports the time spent doing so.
void scanFiles(Set<Source?> files) {
  // The code below will record again how many chars are scanned and how long it
  // takes to scan them, even though we already did so in [scanReachableFiles].
  // Recording and reporting this twice is unnecessary, but we do so for now to
  // validate that the results are consistent.
  scanTimer = Stopwatch();
  var old = scanTotalChars;
  scanTotalChars = 0;
  for (var source in files) {
    tokenize(source!);
  }

  // Report size and scanning time again. See discussion above.
  if (old != scanTotalChars) print('input size changed? $old chars');
  report('scan', scanTimer.elapsedMicroseconds);
}

/// Load and scans all files we need to process: files reachable from the
/// entrypoint and all core libraries automatically included by the VM.
Set<Source?> scanReachableFiles(Uri entryUri) {
  var files = <Source?>{};
  var loadTimer = Stopwatch()..start();
  collectSources(sources.forUri2(entryUri), files);

  var libs = [
    'dart:async',
    'dart:cli',
    'dart:collection',
    'dart:convert',
    'dart:core',
    'dart:developer',
    'dart:_internal',
    'dart:isolate',
    'dart:math',
    'dart:mirrors',
    'dart:typed_data',
    'dart:io',
  ];

  for (var lib in libs) {
    collectSources(sources.forUri(lib), files);
  }

  loadTimer.stop();

  print('input size: $scanTotalChars chars');
  var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
  report('load', loadTime);
  report('scan', scanTimer.elapsedMicroseconds);
  return files;
}

/// Sets up analyzer to be able to load and resolve app, packages, and sdk
/// sources.
Future setup(String path) async {
  var provider = PhysicalResourceProvider.INSTANCE;

  var packages = findPackagesFrom(
    provider,
    provider.getResource(path),
  );

  var packageMap = <String, List<Folder>>{};
  for (var package in packages.packages) {
    packageMap[package.name] = [package.libFolder];
  }

  sources = SourceFactory([
    ResourceUriResolver(provider),
    PackageMapUriResolver(provider, packageMap),
    DartUriResolver(FolderBasedDartSdk(provider, provider.getFolder('sdk'))),
  ]);
}

/// Scan [source] and return the first token produced by the scanner.
Token tokenize(Source source) {
  scanTimer.start();
  var contents = source.contents.data;
  scanTotalChars += contents.length;
  // TODO(paulberry): figure out the appropriate featureSet to use here
  var featureSet = FeatureSet.latestLanguageVersion();
  // TODO(sigmund): is there a way to scan from a random-access-file without
  // first converting to String?
  var scanner = Scanner(
      source, CharSequenceReader(contents), AnalysisErrorListener.NULL_LISTENER)
    ..configureFeatures(
      featureSetForOverriding: featureSet,
      featureSet: featureSet,
    )
    ..preserveComments = false;
  var token = scanner.tokenize();
  scanTimer.stop();
  return token;
}
