// 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:async';
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/file_system/file_system.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.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') {
    Set<Source> files = scanReachableFiles(entryUri);
    // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
    for (int i = 0; i < 10; i++) {
      scanFiles(files);
    }
  } else if (bench == 'parse') {
    Set<Source> files = scanReachableFiles(entryUri);
    // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
    for (int 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.
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 featureSet = FeatureSet.fromEnableFlags([]);
  var parser = Parser(source, AnalysisErrorListener.NULL_LISTENER,
      featureSet: featureSet);
  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 featureSet = FeatureSet.fromEnableFlags([]);
  var parser = Parser(source, AnalysisErrorListener.NULL_LISTENER,
      featureSet: featureSet);
  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.fromEnableFlags([]);
  // 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(featureSet)
    ..preserveComments = false;
  var token = scanner.tokenize();
  scanTimer.stop();
  return token;
}
