// Copyright (c) 2018, 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:async';

import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/utilities/null_string_sink.dart';
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';

/**
 * A runner that can request code completion at the location of each identifier
 * in a Dart file.
 */
class CompletionRunner {
  /**
   * The sink to which output is to be written.
   */
  final StringSink output;

  /**
   * A flag indicating whether to produce output about missing suggestions.
   */
  final bool printMissing;

  /**
   * A flag indicating whether to produce output about the quality of the sort
   * order.
   */
  final bool printQuality;

  /**
   * A flag indicating whether to produce timing information.
   */
  final bool timing;

  /**
   * A flag indicating whether to produce verbose output.
   */
  final bool verbose;

  /**
   * A flag indicating whether we should delete each identifier before
   * attempting to complete at that offset.
   */
  bool deleteBeforeCompletion = false;

  /**
   * Initialize a newly created completion runner.
   */
  CompletionRunner(
      {StringSink output,
      bool printMissing,
      bool printQuality,
      bool timing,
      bool verbose})
      : this.output = output ?? new NullStringSink(),
        this.printMissing = printMissing ?? false,
        this.printQuality = printQuality ?? false,
        this.timing = timing ?? false,
        this.verbose = verbose ?? false;

  /**
   * Test the completion engine at the locations of each of the identifiers in
   * each of the files in the given [analysisRoot].
   */
  Future<void> runAll(String analysisRoot) async {
    OverlayResourceProvider resourceProvider =
        new OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
    AnalysisContextCollection collection = new AnalysisContextCollection(
        includedPaths: <String>[analysisRoot],
        resourceProvider: resourceProvider);
    DartCompletionManager contributor = new DartCompletionManager();
    CompletionPerformance performance = new CompletionPerformance();
    int stamp = 1;

    int fileCount = 0;
    int identifierCount = 0;
    int expectedCount = 0;
    int missingCount = 0;
    List<int> indexCount = new List.filled(20, 0);
    List<int> filteredIndexCount = new List.filled(20, 0);

    // Consider getting individual timings so that we can also report the
    // longest and shortest times, or even a distribution.
    Stopwatch timer = new Stopwatch();

    for (AnalysisContext context in collection.contexts) {
      for (String path in context.contextRoot.analyzedFiles()) {
        if (!path.endsWith('.dart')) {
          continue;
        }
        fileCount++;
        output.write('.');
        ResolveResult result =
            await context.currentSession.getResolvedAst(path);
        String content = result.content;
        LineInfo lineInfo = result.lineInfo;
        List<SimpleIdentifier> identifiers = _identifiersIn(result.unit);

        for (SimpleIdentifier identifier in identifiers) {
          identifierCount++;
          int offset = identifier.offset;
          if (deleteBeforeCompletion) {
            String modifiedContent = content.substring(0, offset) +
                content.substring(identifier.end);
            resourceProvider.setOverlay(path,
                content: modifiedContent, modificationStamp: stamp++);
            result = await context.currentSession.getResolvedAst(path);
          }

          timer.start();
          CompletionRequestImpl request =
              new CompletionRequestImpl(result, offset, performance);
          List<CompletionSuggestion> suggestions =
              await contributor.computeSuggestions(request);
          timer.stop();

          if (!identifier.inDeclarationContext() &&
              !_isNamedExpressionName(identifier)) {
            expectedCount++;
            suggestions = _sort(suggestions.toList());
            int index = _indexOf(suggestions, identifier.name);
            if (index < 0) {
              missingCount++;
              if (printMissing) {
                CharacterLocation location = lineInfo.getLocation(offset);
                output.writeln('Missing suggestion of "${identifier.name}" at '
                    '$path:${location.lineNumber}:${location.columnNumber}');
                if (verbose) {
                  _printSuggestions(suggestions);
                }
              }
            } else if (printQuality) {
              if (index < indexCount.length) {
                indexCount[index]++;
              }
              List<CompletionSuggestion> filteredSuggestions =
                  _filterBy(suggestions, identifier.name.substring(0, 1));
              int filteredIndex =
                  _indexOf(filteredSuggestions, identifier.name);
              if (filteredIndex < filteredIndexCount.length) {
                filteredIndexCount[filteredIndex]++;
              }
            }
          }
        }
        if (deleteBeforeCompletion) {
          resourceProvider.removeOverlay(path);
        }
      }
    }
    output.writeln();
    if (printMissing) {
      output.writeln();
    }
    output.writeln('Found $identifierCount identifiers in $fileCount files');
    if (expectedCount > 0) {
      output.writeln('  $expectedCount were expected to code complete');
      if (printQuality) {
        int percent = (missingCount * 100 / expectedCount).round();
        output.writeln('  $percent% of which were missing suggestions '
            '($missingCount)');

        int foundCount = expectedCount - missingCount;

        void printCount(int count) {
          if (count < 10) {
            output.write('      $count  ');
          } else if (count < 100) {
            output.write('     $count  ');
          } else if (count < 1000) {
            output.write('    $count  ');
          } else if (count < 10000) {
            output.write('   $count  ');
          } else {
            output.write('  $count  ');
          }
          int percent = (count * 100 / foundCount).floor();
          for (int j = 0; j < percent; j++) {
            output.write('-');
          }
          output.writeln();
        }

        void _printCounts(List<int> counts) {
          int nearTopCount = 0;
          for (int i = 0; i < counts.length; i++) {
            int count = counts[i];
            printCount(count);
            nearTopCount += count;
          }
          printCount(foundCount - nearTopCount);
        }

        output.writeln();
        output.writeln('By position in the list');
        _printCounts(indexCount);
        output.writeln();
        output.writeln('By position in the list (filtered by first character)');
        _printCounts(filteredIndexCount);
        output.writeln();
      }
    }
    if (timing && identifierCount > 0) {
      int time = timer.elapsedMilliseconds;
      int averageTime = (time / identifierCount).round();
      output.writeln('completion took $time ms, '
          'which is an average of $averageTime ms per completion');
    }
  }

  List<CompletionSuggestion> _filterBy(
      List<CompletionSuggestion> suggestions, String pattern) {
    return suggestions
        .where((suggestion) => suggestion.completion.startsWith(pattern))
        .toList();
  }

  /**
   * Return a list containing information about the identifiers in the given
   * compilation [unit].
   */
  List<SimpleIdentifier> _identifiersIn(CompilationUnit unit) {
    IdentifierCollector visitor = new IdentifierCollector();
    unit.accept(visitor);
    return visitor.identifiers;
  }

  /**
   * If the given list of [suggestions] includes a suggestion for the given
   * [identifier], return the index of the suggestion. Otherwise, return `-1`.
   */
  int _indexOf(List<CompletionSuggestion> suggestions, String identifier) {
    for (int i = 0; i < suggestions.length; i++) {
      if (suggestions[i].completion == identifier) {
        return i;
      }
    }
    return -1;
  }

  /**
   * Return `true` if the given [identifier] is being used as the name of a
   * named expression.
   */
  bool _isNamedExpressionName(SimpleIdentifier identifier) {
    AstNode parent = identifier.parent;
    return parent is NamedExpression && parent.name == identifier;
  }

  /**
   * Print information about the given [suggestions].
   */
  void _printSuggestions(List<CompletionSuggestion> suggestions) {
    if (suggestions.length == 0) {
      output.writeln('  No suggestions');
      return;
    }
    output.writeln('  Suggestions:');
    for (CompletionSuggestion suggestion in suggestions) {
      output.writeln('    ${suggestion.completion}');
    }
  }

  List<CompletionSuggestion> _sort(List<CompletionSuggestion> suggestions) {
    suggestions.sort((first, second) => second.relevance - first.relevance);
    return suggestions;
  }
}

/**
 * A visitor that will collect simple identifiers in the AST being visited.
 */
class IdentifierCollector extends RecursiveAstVisitor<void> {
  /**
   * The simple identifiers that were collected.
   */
  final List<SimpleIdentifier> identifiers = <SimpleIdentifier>[];

  @override
  visitSimpleIdentifier(SimpleIdentifier node) {
    identifiers.add(node);
  }
}
