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

import 'package:analysis_server/src/services/completion/dart/documentation_cache.dart';
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart' as err;
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:args/args.dart';
import 'package:cli_util/cli_logging.dart';

import 'visitors.dart';

final logger = Logger.standard(ansi: Ansi(Ansi.terminalSupportsAnsi));

/// This is the main metrics computer class for code completions. After the
/// object is constructed, [computeCompletionMetrics] is executed to do analysis
/// and print a summary of the metrics gathered from the completion tests.
abstract class CompletionMetricsComputer {
  final String rootPath;

  final CompletionMetricsOptions options;

  late ResolvedUnitResult resolvedUnitResult;

  final OverlayResourceProvider provider =
      OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);

  int overlayModificationStamp = 0;

  CompletionMetricsComputer(this.rootPath, this.options);

  /// Applies an overlay in [filePath] at [expectedCompletion].
  Future<void> applyOverlay(AnalysisContext context, String filePath,
      ExpectedCompletion expectedCompletion);

  /// Compute the metrics for the files in the context [root], creating a
  /// separate context collection to prevent accumulating memory. The metrics
  /// should be captured in the [collector].
  Future<void> computeInContext(ContextRoot root) async {
    // Create a new collection to avoid consuming large quantities of memory.
    final collection = AnalysisContextCollectionImpl(
      includedPaths: root.includedPaths.toList(),
      excludedPaths: root.excludedPaths.toList(),
      resourceProvider: provider,
    );

    var context = collection.contexts[0];

    setupForResolution(context);

    logger.write('Computing completions at root: ${root.root.path}\n');
    var documentationCache = DocumentationCache(DartdocDirectiveInfo());

    var results = await resolveAnalyzedFiles(
      context: context,
      documentationCache: documentationCache,
    );

    logger.write('Analyzing completion suggestions...\n');
    var progress = ProgressBar(logger, results.length);
    for (var result in results) {
      resolvedUnitResult = result;
      var filePath = result.path;
      // Use the ExpectedCompletionsVisitor to compute the set of expected
      // completions for this CompilationUnit.
      final visitor =
          ExpectedCompletionsVisitor(result, caretOffset: options.prefixLength);
      resolvedUnitResult.unit.accept(visitor);

      for (var expectedCompletion in visitor.expectedCompletions) {
        await applyOverlay(context, filePath, expectedCompletion);

        await computeSuggestionsAndMetrics(
          expectedCompletion,
          context,
          documentationCache,
        );

        await removeOverlay(filePath);
      }
      progress.tick();
    }
    progress.complete();
  }

  Future<void> computeMetrics() async {
    final collection = AnalysisContextCollectionImpl(
      includedPaths: [rootPath],
      resourceProvider: PhysicalResourceProvider.INSTANCE,
    );
    for (final context in collection.contexts) {
      await computeInContext(context.contextRoot);
    }
  }

  /// Computes suggestions for [expectedCompletion] and computes metrics from
  /// the resulting suggestions.
  Future<void> computeSuggestionsAndMetrics(
    ExpectedCompletion expectedCompletion,
    AnalysisContext context,
    DocumentationCache documentationCache,
  );

  /// Removes the overlay which has been applied to [filePath].
  Future<void> removeOverlay(String filePath);

  /// Resolves all analyzed files within [context].
  Future<List<ResolvedUnitResult>> resolveAnalyzedFiles({
    required AnalysisContext context,
    required DocumentationCache documentationCache,
  }) async {
    final analyzedFileCount = context.contextRoot.analyzedFiles().length;
    logger.write('Resolving $analyzedFileCount files...\n');

    final progress = ProgressBar(logger, analyzedFileCount);
    final results = <ResolvedUnitResult>[];
    final pathContext = context.contextRoot.resourceProvider.pathContext;
    for (final filePath in context.contextRoot.analyzedFiles()) {
      if (file_paths.isDart(pathContext, filePath)) {
        try {
          final result = await context.currentSession.getResolvedUnit(filePath)
              as ResolvedUnitResult;

          final analysisError = getFirstErrorOrNull(result);
          if (analysisError != null) {
            progress.clear();
            print('File $filePath skipped due to errors such as:');
            print('  ${analysisError.toString()}');
            print('');
            continue;
          } else {
            results.add(result);
            documentationCache.cacheFromResult(result);
          }
        } catch (exception, stackTrace) {
          progress.clear();
          print('Exception caught analyzing: $filePath');
          print(exception.toString());
          print(stackTrace);
        }
      }
      progress.tick();
    }
    progress.complete();
    return results;
  }

  /// Performs setup tasks with [context] before resolution.
  void setupForResolution(AnalysisContext context);

  /// Given some [ResolvedUnitResult] returns the first error of high severity
  /// if such an error exists, `null` otherwise.
  static err.AnalysisError? getFirstErrorOrNull(
      ResolvedUnitResult resolvedUnitResult) {
    for (final error in resolvedUnitResult.errors) {
      if (error.severity == Severity.error) {
        return error;
      }
    }
    return null;
  }

  /// Gets overlay content for [content], applying a change at
  /// [expectedCompletion] with [prefixLength], according to [overlay], one of
  /// the [CompletionMetricsOptions].
  static String getOverlayContent(
    String content,
    ExpectedCompletion expectedCompletion,
    OverlayMode overlay,
    int prefixLength,
  ) {
    assert(content.isNotEmpty);
    var offset = expectedCompletion.offset;
    final length = expectedCompletion.syntacticEntity.length;
    assert(offset >= 0);
    assert(length > 0);
    var tokenEndOffset = offset + length;
    if (length >= prefixLength) {
      // Rather than removing the whole token, remove the characters after
      // the given prefix length.
      offset += prefixLength;
    }
    if (overlay == OverlayMode.removeToken) {
      return content.substring(0, offset) + content.substring(tokenEndOffset);
    } else if (overlay == OverlayMode.removeRestOfFile) {
      return content.substring(0, offset);
    } else {
      throw ArgumentError.value(overlay, 'overlay');
    }
  }
}

/// The options specified on the command-line.
class CompletionMetricsOptions {
  /// An option to control whether and how overlays should be produced.
  static const String OVERLAY = 'overlay';

  /// An option controlling how long of a prefix should be used.
  ///
  /// This affects the offset of the completion request, and how much content is
  /// removed in each of the overlay modes.
  static const String PREFIX_LENGTH = 'prefix-length';

  /// A flag that causes information to be printed about the completion requests
  /// that were the slowest to return suggestions.
  static const String PRINT_SLOWEST_RESULTS = 'print-slowest-results';

  /// The overlay mode that should be used.
  final OverlayMode overlay;

  final int prefixLength;

  /// A flag indicating whether information should be printed about the
  /// completion requests that were the slowest to return suggestions.
  final bool printSlowestResults;

  CompletionMetricsOptions(ArgResults results)
      : overlay = OverlayMode.parseFlag(results[OVERLAY] as String),
        prefixLength = int.parse(results[PREFIX_LENGTH] as String),
        printSlowestResults = results[PRINT_SLOWEST_RESULTS] as bool;
}

enum OverlayMode {
  /// A mode indicating that no overlays should be produced.
  none('none'),

  /// A mode indicating that everything from the completion offset to the end of
  /// the file should be removed.
  removeRestOfFile('remove-rest-of-file'),

  /// A mode indicating that the token whose offset is the same as the
  /// completion offset should be removed.
  removeToken('remove-token');

  final String flag;

  const OverlayMode(this.flag);

  static OverlayMode parseFlag(String flag) {
    for (final mode in values) {
      if (flag == mode.flag) {
        return mode;
      }
    }
    throw ArgumentError.value(flag, 'overlay');
  }
}

/// A facility for drawing a progress bar in the terminal.
///
/// The bar is instantiated with the total number of "ticks" to be completed,
/// and progress is made by calling [tick]. The bar is drawn across one entire
/// line, like so:
///
///     [----------                                                   ]
///
/// The hyphens represent completed progress, and the whitespace represents
/// remaining progress.
///
/// If there is no terminal, the progress bar will not be drawn.
class ProgressBar {
  /// Whether the progress bar should be drawn.
  late bool _shouldDrawProgress;

  /// The width of the terminal, in terms of characters.
  late int _width;

  final Logger _logger;

  /// The inner width of the terminal, in terms of characters.
  ///
  /// This represents the number of characters available for drawing progress.
  late int _innerWidth;

  final int _totalTickCount;

  int _tickCount = 0;

  ProgressBar(this._logger, this._totalTickCount) {
    if (!stdout.hasTerminal) {
      _shouldDrawProgress = false;
    } else {
      _shouldDrawProgress = true;
      _width = stdout.terminalColumns;
      // Inclusion of the percent indicator assumes a terminal width of at least
      // 12 (2 brackets + 1 space + 2 parenthesis characters + 3 digits +
      // 1 period + 2 digits + 1 '%' character).
      _innerWidth = stdout.terminalColumns - 12;
      _logger.write('[${' ' * _innerWidth}]');
    }
  }

  /// Clears the progress bar from the terminal, allowing other logging to be
  /// printed.
  void clear() {
    if (!_shouldDrawProgress) {
      return;
    }
    _logger.write('\r${' ' * _width}\r');
  }

  /// Draws the progress bar as complete, and print two newlines.
  void complete() {
    if (!_shouldDrawProgress) {
      return;
    }
    _logger.write('\r[${'-' * _innerWidth}]\n\n');
  }

  /// Progresses the bar by one tick.
  void tick() {
    if (!_shouldDrawProgress) {
      return;
    }
    _tickCount++;
    final fractionComplete =
        math.max(0, _tickCount * _innerWidth ~/ _totalTickCount - 1);
    // The inner space consists of hyphens, one spinner character, spaces, and a
    // percentage (8 characters).
    final hyphens = '-' * fractionComplete;
    final trailingSpace = ' ' * (_innerWidth - fractionComplete - 1);
    final spinner = AnsiProgress.kAnimationItems[_tickCount % 4];
    final pctComplete = (_tickCount * 100 / _totalTickCount).toStringAsFixed(2);
    _logger.write('\r[$hyphens$spinner$trailingSpace] ($pctComplete%)');
  }
}
