// Copyright (c) 2020, 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:io';
import 'dart:math' as math;

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:args/args.dart';
import 'package:path/path.dart' as p;

import 'src/error_listener.dart';
import 'src/histogram.dart';
import 'src/scrape_visitor.dart';

export 'src/histogram.dart';
export 'src/scrape_visitor.dart' hide bindVisitor;

class Scrape {
  final List<ScrapeVisitor Function()> _visitorFactories = [];

  /// What percent of files should be processed.
  int? _percent;

  /// Process package test files.
  bool _includeTests = true;

  /// Process Dart SDK language tests.
  bool _includeLanguageTests = true;

  /// Process Dart files generated from protobufs.
  bool _includeProtobufs = false;

  /// Whether every file should be printed before being processed.
  bool _printFiles = true;

  /// Whether parse errors should be printed.
  bool _printErrors = true;

  /// The number of files that have been processed.
  int get scrapedFileCount => _scrapedFileCount;
  int _scrapedFileCount = 0;

  /// The number of lines of code that have been processed.
  int get scrapedLineCount => _scrapedLineCount;
  int _scrapedLineCount = 0;

  /// The number of files that could not be parsed.
  int get errorFileCount => _errorFileCount;
  int _errorFileCount = 0;

  final Map<String, Histogram> _histograms = {};

  /// Whether we're in the middle of writing the running file count and need a
  /// newline before any other output should be shown.
  bool _needClearLine = false;

  /// Register a new visitor factory.
  ///
  /// This function will be called for each scraped file and the resulting
  /// [ScrapeVisitor] will traverse the parsed file's AST.
  void addVisitor(ScrapeVisitor Function() createVisitor) {
    _visitorFactories.add(createVisitor);
  }

  /// Defines a new histogram with [name] to collect occurrences.
  ///
  /// After the scrape completes, each defined histogram's collected counts
  /// are shown, ordered by [order]. If [showBar] is not `false`, then shows an
  /// ASCII bar chart for the counts.
  ///
  /// If [showAll] is `true`, then every item that occurred is shown. Otherwise,
  /// only shows the first 100 items or occurrences that represent at least
  /// 0.1% of the total, whichever is longer.
  ///
  /// If [minCount] is passed, then only shows items that occurred at least
  /// that many times.
  void addHistogram(String name,
      {SortOrder order = SortOrder.descending,
      bool? showBar,
      bool? showAll,
      int? minCount}) {
    _histograms.putIfAbsent(
        name,
        () => Histogram(
            order: order,
            showBar: showBar,
            showAll: showAll,
            minCount: minCount));
  }

  /// Add an occurrence of [item] to [histogram].
  void record(String histogram, Object item) {
    _histograms[histogram]!.add(item);
  }

  /// Run the scrape using the given set of command line arguments.
  void runCommandLine(List<String> arguments) {
    var parser = ArgParser(allowTrailingOptions: true);
    parser.addOption('percent',
        help: 'Only process a randomly selected percentage of files.');
    parser.addFlag('tests',
        defaultsTo: true, help: 'Process package test files.');
    parser.addFlag('language-tests',
        help: 'Process Dart SDK language test files.');
    parser.addFlag('protobufs',
        help: 'Process Dart files generated from protobufs.');
    parser.addFlag('print-files',
        defaultsTo: true, help: 'Print the path for each parsed file.');
    parser.addFlag('print-errors',
        defaultsTo: true, help: 'Print parse errors.');
    parser.addFlag('help', negatable: false, help: 'Print help text.');

    var results = parser.parse(arguments);

    if (results['help'] as bool) {
      var script = p.url.basename(Platform.script.toString());
      print('Usage: $script [options] <paths...>');
      print(parser.usage);
      return;
    }

    _includeTests = results['tests'] as bool;
    _includeLanguageTests = results['language-tests'] as bool;
    _includeProtobufs = results['protobufs'] as bool;
    _printFiles = results['print-files'] as bool;
    _printErrors = results['print-errors'] as bool;

    if (results.wasParsed('percent')) {
      _percent = int.tryParse(results['percent'] as String);
      if (_percent == null) {
        print("--percent must be an integer, was '${results["percent"]}'.");
        exit(1);
      }
    }

    if (results.rest.isEmpty) {
      print('Must pass at least one path to process.');
      exit(1);
    }

    var watch = Stopwatch()..start();
    for (var path in results.rest) {
      _processPath(path);
    }
    watch.stop();

    clearLine();
    _histograms.forEach((name, histogram) {
      histogram.printCounts(name);
    });

    String count(int n, String unit) {
      if (n == 1) return '1 $unit';
      return '$n ${unit}s';
    }

    var elapsed = _formatDuration(watch.elapsed);
    var lines = count(_scrapedLineCount, 'line');
    var files = count(_scrapedFileCount, 'file');
    var message = 'Took $elapsed to scrape $lines in $files.';

    if (_errorFileCount > 0) {
      var errors = count(_errorFileCount, 'file');
      message += ' ($errors could not be parsed.)';
    }

    print(message);
  }

  /// Display [message], clearing the line if necessary.
  void log(Object message) {
    // TODO(rnystrom): Consider using cli_util package.
    clearLine();
    print(message);
  }

  /// Clear the current line if it needs it.
  void clearLine() {
    if (!_needClearLine) return;
    stdout.write('\u001b[2K\r');
    _needClearLine = false;
  }

  String _formatDuration(Duration duration) {
    String pad(int width, int n) => n.toString().padLeft(width, '0');

    if (duration.inMinutes >= 1) {
      var minutes = duration.inMinutes;
      var seconds = duration.inSeconds % 60;
      var ms = duration.inMilliseconds % 1000;
      return '$minutes:${pad(2, seconds)}.${pad(3, ms)}';
    } else if (duration.inSeconds >= 1) {
      return '${(duration.inMilliseconds / 1000).toStringAsFixed(3)}s';
    } else {
      return '${duration.inMilliseconds}ms';
    }
  }

  void _processPath(String path) {
    var random = math.Random();

    if (File(path).existsSync()) {
      _parseFile(File(path), path);
      return;
    }

    for (var entry in Directory(path).listSync(recursive: true)) {
      if (entry is! File) continue;

      if (!entry.path.endsWith('.dart')) continue;

      // For unknown reasons, some READMEs have a ".dart" extension. They aren't
      // Dart files.
      if (entry.path.endsWith('README.dart')) continue;

      if (!_includeLanguageTests) {
        if (entry.path.contains('/sdk/tests/')) continue;
        if (entry.path.contains('/testcases/')) continue;
        if (entry.path.contains('/sdk/runtime/tests/')) continue;
        if (entry.path.contains('/linter/test/_data/')) continue;
        if (entry.path.contains('/analyzer/test/')) continue;
        if (entry.path.contains('/dev_compiler/test/')) continue;
        if (entry.path.contains('/analyzer_cli/test/')) continue;
        if (entry.path.contains('/analysis_server/test/')) continue;
        if (entry.path.contains('/kernel/test/')) continue;
      }

      if (!_includeTests) {
        if (entry.path.contains('/test/')) continue;
        if (entry.path.endsWith('_test.dart')) continue;
      }

      // Don't care about cached packages.
      if (entry.path.contains('sdk/third_party/pkg/')) continue;
      if (entry.path.contains('sdk/third_party/pkg_tested/')) continue;
      if (entry.path.contains('/.dart_tool/')) continue;

      // Don't care about generated protobuf code.
      if (!_includeProtobufs) {
        if (entry.path.endsWith('.pb.dart')) continue;
        if (entry.path.endsWith('.pbenum.dart')) continue;
      }

      if (_percent != null && random.nextInt(100) >= _percent!) continue;

      var relative = p.relative(entry.path, from: path);
      _parseFile(entry, relative);
    }
  }

  void _parseFile(File file, String shortPath) {
    var source = file.readAsStringSync();

    var errorListener = ErrorListener(this, _printErrors);
    var featureSet = FeatureSet.latestLanguageVersion();

    // Tokenize the source.
    var reader = CharSequenceReader(source);
    var stringSource = StringSource(source, file.path);
    var scanner = Scanner(stringSource, reader, errorListener);
    scanner.configureFeatures(
        featureSet: featureSet, featureSetForOverriding: featureSet);
    var startToken = scanner.tokenize();

    // Parse it.
    var parser = Parser(stringSource, errorListener, featureSet: featureSet);
    parser.enableOptionalNewAndConst = true;
    parser.enableSetLiterals = true;

    if (_printFiles) {
      var line =
          '[$_scrapedFileCount files, $_scrapedLineCount lines] ' '$shortPath';
      if (Platform.isWindows) {
        // No ANSI escape codes on Windows.
        print(line);
      } else {
        // Overwrite the same line.
        stdout.write('\u001b[2K\r'
            '[$_scrapedFileCount files, $_scrapedLineCount lines] $shortPath');
        _needClearLine = true;
      }
    }

    AstNode node;
    try {
      node = parser.parseCompilationUnit(startToken);
    } catch (error) {
      print('Got exception parsing $shortPath:\n$error');
      return;
    }

    // Don't process files with syntax errors.
    if (errorListener.hadError) {
      _errorFileCount++;
      return;
    }

    var lineInfo = LineInfo(scanner.lineStarts);

    _scrapedFileCount++;
    _scrapedLineCount += lineInfo.lineCount;

    for (var visitorFactory in _visitorFactories) {
      var visitor = visitorFactory();
      bindVisitor(visitor, this, shortPath, source, lineInfo);
      node.accept(visitor);
    }
  }
}
