// Copyright (c) 2019, 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 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/linter_visitor.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:front_end/src/fasta/fasta_codes.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:source_span/src/span.dart';

/// A task for fixing a particular lint.
/// Subclasses should implement [applyLocalFixes] and [applyRemainingFixes]
/// and may override any of the reportSomething() methods as needed.
abstract class FixLintTask implements ErrorReporter {
  final DartFixListener listener;

  @override
  Source source;

  FixLintTask(this.listener);

  /// Apply fixes for the current compilation unit.
  Future<void> applyLocalFixes(ResolvedUnitResult result);

  /// Apply any fixes remaining after all local changes have been applied.
  Future<void> applyRemainingFixes();

  @override
  void reportError(AnalysisError error) {
    // ignored
  }

  @override
  void reportErrorForElement(ErrorCode errorCode, Element element,
      [List<Object> arguments]) {
    // ignored
  }

  @override
  void reportErrorForNode(ErrorCode errorCode, AstNode node,
      [List<Object> arguments]) {
    // ignored
  }

  @override
  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
      [List<Object> arguments]) {
    // ignored
  }

  @override
  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
      [List<Object> arguments]) {
    // ignored
  }

  @override
  void reportErrorForToken(ErrorCode errorCode, Token token,
      [List<Object> arguments]) {
    // ignored
  }

  @override
  void reportErrorMessage(
      ErrorCode errorCode, int offset, int length, Message message) {
    // ignored
  }

  @override
  void reportTypeErrorForNode(
      ErrorCode errorCode, AstNode node, List<Object> arguments) {
    // ignored
  }
}

/// A processor used by [EditDartFix] to manage [FixLintTask]s.
mixin FixLintProcessor {
  final linters = <Linter>[];
  final lintTasks = <FixLintTask>[];

  Future<void> finishLints() async {
    for (Linter linter in linters) {
      linter.reporter = null;
    }
    for (FixLintTask fix in lintTasks) {
      fix.source = null;
      await fix.applyRemainingFixes();
    }
  }

  Future<void> processLints(ResolvedUnitResult result) async {
    // TODO(danrubel): Determine if a lint is configured to run as part of
    // standard analysis and use those results if available instead of
    // running the lint again.

    Source source = result.unit.declaredElement.source;
    for (Linter linter in linters) {
      if (linter != null) {
        linter.reporter.source = source;
      }
    }

    // TODO(paulberry): use an API that provides this information more readily

    var unitElement = result.unit.declaredElement;
    var session = result.session;
    var currentUnit = LinterContextUnit(result.content, result.unit);
    var allUnits = <LinterContextUnit>[];
    for (var cu in unitElement.library.units) {
      if (identical(cu, unitElement)) {
        allUnits.add(currentUnit);
      } else {
        Source source = cu.source;
        if (source != null) {
          var result = await session.getResolvedUnit(source.fullName);
          allUnits.add(LinterContextUnit(result.content, result.unit));
        }
      }
    }

    final visitors = <AstVisitor>[];
    final registry = new NodeLintRegistry(false);
    var context = LinterContextImpl(
        allUnits,
        currentUnit,
        session.declaredVariables,
        result.typeProvider,
        result.typeSystem,
        result.session.analysisContext.analysisOptions);
    for (Linter linter in linters) {
      if (linter != null) {
        final visitor = linter.getVisitor();
        if (visitor != null) {
          visitors.add(visitor);
        }
        if (linter is NodeLintRule) {
          (linter as NodeLintRule).registerNodeProcessors(registry, context);
        }
      }
    }

    CompilationUnit unit = result.unit;
    if (visitors.isNotEmpty) {
      unit.accept(new ExceptionHandlingDelegatingAstVisitor(
          visitors, ExceptionHandlingDelegatingAstVisitor.logException));
    }
    unit.accept(new LinterVisitor(
        registry, ExceptionHandlingDelegatingAstVisitor.logException));

    for (FixLintTask fix in lintTasks) {
      await fix.applyLocalFixes(result);
    }
  }

  void registerLintTask(LintRule lint, FixLintTask task) {
    linters.add(lint);
    lintTasks.add(task);
    lint.reporter = task;
  }
}
